Javascript中创建对象的几种方式讨论

本文中介绍了javascript中创建对象的几种方式,并给出了几种创建方式的异同。(通俗的讲,如何在javascript“生出一个对象”)

对象的分类

在一切皆对象的Javascript中,对象可以分为以下几类:

  • 内部对象
    javascript中的内部对象有:Array、Boolean、Date、Function、Global、Math、Number、Object、RegExp、String以及各种处理错误的对象。其中Global和Math又称为“内置对象”,这两个对象在脚本程序初始化时被自动创建,不必实例化这两个对象。(个人理解,类似于java中静态类的概念,不必实例化直接调用。)

  • 宿主对象
    由执行javacript脚本的宿主环境提供的对象。目前的宿主环境大致为浏览器环境以及Node环境。在浏览器环境中,不同浏览器提供的宿主对象可能不同,存在一定的浏览器兼容问题。

  • 自定义对象
    开发人员自定义的对象。通过在开发中自定义一些对象,实现一定的功能。

创建自定义对象的几种方式对比

字面量方式

javascript中允许开发人员以字面量方式直接创建对象。如下所示:

1
2
3
4
5
6
7
8
var author = {
name: 'monster1935',
age: '24'
};
// or
var author = {};
author.name = 'monster1935';
author.age = '24';

上述定义了一个author对象,该对象拥有两个属性,name以及age。通过author.name或者author[‘name’]方式可以获取对应属性的值。字面量方式创建的对象默认继承自Object.prototype对象。

new Object()方式

通过new Object()方式同样可以创建自定义对象,这种方式创建的对象与字面量的方式本质上相同。该两种方式创建的自定义对象默认继承自Object.prototype的属性和方法。

1
2
3
4
5
6
7
8
9
var author = new Object({
name: 'monster935',
age: '24'
});
// or
var author = new Object();
author.name = 'monster1935';
author.age = '24';

Object.create()的方式

Object.create()方法创建一个拥有指定原型和若干指定属性的对象。

Object.create(proto,[propertiesObject]);

proto: 作为新创建对象的原型,为null或者一个对象值,否则抛出一个Typeerror异常。

propertiesObject: 可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)

以上是来自javascript MDN的关于Object.create()方法的描述。 不同于前两种方式,通过Object.create()方法创建的自定义对象可以指定继承的对象。

1
2
3
4
5
6
7
8
var author = Object.create(null);
author.name = 'monster1935';
author.age = '24';
// or
var author = Object.create(null,{
name: { writable: true, configurable: true, value: 'monster1935'},
age: { writable: true, configurable: true, value: '24'},
});

上述创建的author对象中无__proto__字段,即没有继承来自其他对象的属性。因为在创建时,指定了需继承的对象为null。

知识延伸

** 关于javascript中创建空对象的思考**
由前面的叙述可知,创建空对象可以由以上三种方式创建。

  • var empty = {};
  • var empty = new Object();
  • var empty = Object.create(null);

以上三种方式均可以创建一个空对象。很显然,经过上面三种方式创建自定义对象的方式的比较,我们可知,由Object.create(null)方式创建的空对象显然更’空’,这种方式创建的对象没有继承其他任何对象,因此也就没有__proto__字段。而字面量方式以及对象初始化方式创建的空对象均含有__proto__字段指向默认继承的Object.prototype对象。

** 创建空对象的应用场景 **
《You Don’t Know JS》中一书中有对关于this的绑定的讨论。其中关于如何更安全的显示绑定this的论述中提到了空对象的用法。其大致思想就是创建一个空对象来作为this的绑定,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo(a,b){
console.log('a: ' + a + 'b: ' + b );
}

var empty = Object.create(null);

// use apply to change the this
foo.apply(empty,[2,3]);

// use bind to change the this
var bar = foo.bind(empty,2);
bar(3);


在不需要绑定this的值时却需要动态的传参时,通常做法是动态的绑定this的值为null。这种方式的this值绑定,会使得函数在被调用时对this默认绑定到全局或者undefined(严格模式)。为保证程序的安全性,此处使用空对象的方式,将this绑定了该空对象,确保了程序运行过程中的安全性。很显然通过Object.create(null)方式创建的空对象更‘空’,更大程度上确保了不会对其他处代码产生影响。


参考文章:

作者

monster1935

发布于

2017-01-05

更新于

2024-09-25

许可协议