下面这些基于构造函数的创建对象的语法有什么区别:

person = new Object()

...这个文字语法:

person = {
    property1 : "Hello"
};

看起来两者都做同样的事情,尽管JSLint更喜欢使用对象文字表示法。

哪个更好,为什么?


当前回答

我发现ES6/ES2015有一个不同之处。不能使用简写箭头函数语法返回对象,除非用new object()包围对象。

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

这是因为编译器被{}括号搞糊涂了,认为n: i是一个label:语句结构;分号是可选的,所以它不会抱怨。

如果向对象添加另一个属性,它最终会抛出一个错误。

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :

其他回答

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

这里的每个人都在谈论这两者的相似之处。我会指出它们的不同之处。

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

这里有很多很好的答案,但我想用我的50美分来回答。

所有这些答案所缺少的是一个简单的类比,它适用于刚开始学习编程语言的人。

希望我能用这个类比来填补这个空白:

对象文字创建vs基于构造函数的语法

感受句子创作的不同之处。

如果我有一句话“我喜欢奶酪”,我可以清楚响亮地(字面上,或逐字逐句地)告诉你:我喜欢奶酪。

这是我逐字逐句创造的句子。

所有其他的方法都是一些棘手的方法来让你理解我到底创造了什么句子。例如,我告诉你:

在我的句子中,主语是“I”,宾语是“cheese”,谓词是“to like”。 这是你学习同一句话的另一种方式,没有任何歧义:“我喜欢奶酪”。

Or,

我的句子有3个单词:第一个是英语字典里的第n个单词,第二个是英语字典里的第m个单词,最后一个是英语字典里的第l个单词。

在这种情况下,你也会得到同样的结果:你确切地知道这句话是什么。

你可以设计任何其他方法,这将不同于“逐字”的句子创建(字面),这将是间接(非字面,非逐字)的句子创建方法。

我认为这是这里的核心概念。

唯一一次我将使用'new' keyowrd对象初始化是在内联箭头函数:

() => new Object({ key: value})

因为下面的代码是无效的:

() => { key: value} //  instead of () => { return { key: value};}

在JavaScript中,我们可以用两种方式声明一个新的空对象:

var obj1 = new Object();  
var obj2 = {};  

我没有发现任何迹象表明这两家公司在幕后的运作方式有任何显著差异(如果我错了,请纠正我——我很想知道)。然而,第二种方法(使用对象文字表示法)提供了一些优点。

它更短(准确地说是10个字符) 动态创建对象更容易,也更结构化 如果某个小丑无意中覆盖了Object也没关系

考虑一个包含成员Name和TelNo的新对象。使用新的Object()约定,我们可以像这样创建它:

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

JavaScript的Expando Properties特性允许我们以这种方式动态地创建新成员,我们实现了我们的意图。但是,这种方式不是非常结构化或封装的。如果我们希望在创建时指定成员,而不必依赖于expando属性和创建后赋值,该怎么办?

这就是对象文字表示法可以帮助的地方:

var obj1 = {Name:"A Person",TelNo="12345"};  

在这里,我们用一行代码和更少的字符实现了同样的效果。

关于上述对象构造方法的进一步讨论可以在:JavaScript和面向对象编程(OOP)中找到。

最后,那个覆盖Object的白痴呢?你觉得不可能吗?这个JSFiddle证明了事实并非如此。使用对象文字表示法可以防止我们犯这种错误。

(来自http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)