下面这些基于构造函数的创建对象的语法有什么区别:
person = new Object()
...这个文字语法:
person = {
property1 : "Hello"
};
看起来两者都做同样的事情,尽管JSLint更喜欢使用对象文字表示法。
哪个更好,为什么?
下面这些基于构造函数的创建对象的语法有什么区别:
person = new Object()
...这个文字语法:
person = {
property1 : "Hello"
};
看起来两者都做同样的事情,尽管JSLint更喜欢使用对象文字表示法。
哪个更好,为什么?
当前回答
如果您创建10,000个实例,内存使用情况将有所不同。 new Object()将只保留一个副本,而{}将保留10,000个副本。
其他回答
在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/)
对于没有方法的简单对象(如您的示例)没有区别。 然而,当开始向对象添加方法时,就有很大的不同了。
文字:
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方法的副本。而在原型方法中,方法定义在对象原型中,并在所有对象实例之间共享。 如果有很多对象或方法,文字方式会导致相当大的内存浪费。
唯一一次我将使用'new' keyowrd对象初始化是在内联箭头函数:
() => new Object({ key: value})
因为下面的代码是无效的:
() => { key: value} // instead of () => { return { key: value};}
我发现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 :
另外,根据O'Really的一些javascript书籍....(引用)
使用字面量而不是Object构造函数的另一个原因是没有作用域解析。因为有可能您已经创建了具有相同名称的局部构造函数,解释器需要从调用Object()的位置一直查找作用域链,直到找到全局Object构造函数。