下面这些基于构造函数的创建对象的语法有什么区别:
person = new Object()
...这个文字语法:
person = {
property1 : "Hello"
};
看起来两者都做同样的事情,尽管JSLint更喜欢使用对象文字表示法。
哪个更好,为什么?
下面这些基于构造函数的创建对象的语法有什么区别:
person = new Object()
...这个文字语法:
person = {
property1 : "Hello"
};
看起来两者都做同样的事情,尽管JSLint更喜欢使用对象文字表示法。
哪个更好,为什么?
当前回答
在我的机器上使用Node.js,我运行如下:
console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');
console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');
console.log('Testing Object:');
console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');
console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');
注意,这是这里的扩展:为什么arr =[]比arr = new Array快?
我的输出如下:
Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms
因此,显然{}和[]在创建空对象/数组时比使用new更快。
其他回答
这里的每个人都在谈论这两者的相似之处。我会指出它们的不同之处。
Using new Object() allows you to pass another object. The obvious outcome is that the newly created object will be set to the same reference. Here is a sample code: var obj1 = new Object(); obj1.a = 1; var obj2 = new Object(obj1); obj2.a // 1 The usage is not limited to objects as in OOP objects. Other types could be passed to it too. The function will set the type accordingly. For example if we pass integer 1 to it, an object of type number will be created for us. var obj = new Object(1); typeof obj // "number" The object created using the above method (new Object(1)) would be converted to object type if a property is added to it. var obj = new Object(1); typeof obj // "number" obj.a = 2; typeof obj // "object" If the object is a copy of a child class of object, we could add the property without the type conversion. var obj = new Object("foo"); typeof obj // "object" obj === "foo" // true obj.a = 1; obj === "foo" // true obj.a // 1 var str = "foo"; str.a = 1; str.a // undefined
对于没有方法的简单对象(如您的示例)没有区别。 然而,当开始向对象添加方法时,就有很大的不同了。
文字:
function Obj( prop ) {
return {
p : prop,
sayHello : function(){ alert(this.p); },
};
}
原型:
function Obj( prop ) {
this.p = prop;
}
Obj.prototype.sayHello = function(){alert(this.p);};
这两种方法都允许像这样创建Obj实例:
var foo = new Obj( "hello" );
然而,使用文字方式,在对象的每个实例中携带sayHello方法的副本。而在原型方法中,方法定义在对象原型中,并在所有对象实例之间共享。 如果有很多对象或方法,文字方式会导致相当大的内存浪费。
2019年更新
我在OSX High Sierra 10.13.6节点10.13.0版本上运行了与@rjloura相同的代码,这些是结果
console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');
console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');
console.log('Testing Object:');
console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');
console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');
Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms
Actually, there are several ways to create objects in JavaScript. When you just want to create an object there's no benefit of creating "constructor-based" objects using "new" operator. It's same as creating an object using "object literal" syntax. But "constructor-based" objects created with "new" operator comes to incredible use when you are thinking about "prototypal inheritance". You cannot maintain inheritance chain with objects created with literal syntax. But you can create a constructor function, attach properties and methods to its prototype. Then if you assign this constructor function to any variable using "new" operator, it will return an object which will have access to all of the methods and properties attached with the prototype of that constructor function.
下面是一个使用构造函数创建对象的例子(参见底部的代码说明):
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Person.prototype.fullname = function() {
console.log(this.firstname + ' ' + this.lastname);
}
var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');
zubaer.fullname();
john.fullname();
现在,您可以通过实例化Person构造函数创建任意多的对象,所有这些对象都将从它继承fullname()。
注意: “this”关键字将引用构造函数中的一个空对象,每当您使用“new”操作符从Person创建一个新对象时,它将自动返回一个包含所有属性和方法的对象,并附加“this”关键字。而且这些对象肯定会继承Person构造函数原型附带的方法和属性(这是这种方法的主要优点)。
顺便说一下,如果你想用“对象文字”语法获得相同的功能,你必须在所有对象上创建fullname(),如下所示:
var zubaer = {
firstname: 'Zubaer',
lastname: 'Ahammed',
fullname: function() {
console.log(this.firstname + ' ' + this.lastname);
}
};
var john= {
firstname: 'John',
lastname: 'Doe',
fullname: function() {
console.log(this.firstname + ' ' + this.lastname);
}
};
zubaer.fullname();
john.fullname();
最后,如果你现在问我为什么要使用构造函数方法而不是对象文字方法:
原型继承允许一个简单的继承链,这是非常有用和强大的。
***通过继承构造函数原型中定义的通用方法和属性来节省内存。否则,你必须在所有对象中一遍又一遍地复制它们。
我希望这是有意义的。
另外,根据O'Really的一些javascript书籍....(引用)
使用字面量而不是Object构造函数的另一个原因是没有作用域解析。因为有可能您已经创建了具有相同名称的局部构造函数,解释器需要从调用Object()的位置一直查找作用域链,直到找到全局Object构造函数。