用{}或new Object()在JavaScript中创建一个空对象?

421

在 JavaScript 中,创建一个空对象有两种不同的方式:

var objectA = {}
var objectB = new Object()

脚本引擎在处理它们时有区别吗?有没有使用一个而不是另一个的原因?

同样,也可以使用不同的语法创建空数组:

var arrayA = []
var arrayB = new Array()

7
警告:有一个细微的差别可能会导致非常令人烦恼的错误!在对象原型中创建一个空对象并将其赋值为“{}”将成为由“new”运算符创建的每个对象实例中的同一对象实例。而使用“new Object({})”时,您会得到不同的实例。 - peterh
值得一提的是,除了var objectA = {} var objectB = new Object()还有第三种构造方式可以产生相同的结果:var objectC = Object.create(Object.prototype); - kalitsov
使用{}代替new Object()。使用[]代替new Array()。当成员名称为连续整数时,请使用数组。当成员名称为任意字符串或名称时,请使用对象。来源 - ilgaar
2
new Object(){} 并不是完全空的对象,它们是具有 Object.prototype 的对象。您可以使用 Object.create(null) 来创建一个真正的空对象(至少根据 Mozilla 文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)。 - user9903
10个回答

514

对象

使用new Object()没有好处,而{}可以使你的代码更加简洁、易读。

对于定义空对象,它们在技术上是相同的。 {}语法更短、更整洁(不太像Java),并允许你立即内嵌填充对象,如下所示:

var myObject = {
  title: 'Frog',
  url: '/img/picture.jpg',
  width: 300,
  height: 200
};

数组

对于数组,使用[]几乎总是比new Array()更好——只有一种小例外:

var emptyArray = new Array(100);

创建一个包含100个undefined的数组,这在某些情况下可能很好用(例如(new Array(9)).join('Na-Na ') + 'Batman!')。

我的建议

  1. 永远不要使用new Object();——它比{}更笨重,看起来很傻。
  2. 始终使用[]——除非你需要快速创建一个具有预定义长度的“空”数组。

24
即使使用Array(100)语法,该数组在第101个位置仍然包含undefined值;这个数字真正做的只是改变length属性的值。 - Jason Bunting
6
@Pablo,new Array(100)并没有任何问题。请阅读文献:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array - Már Örlygsson
9
@Pablo,我不明白你的论点。像Douglas Crockford一样,我建议使用[]。在这一点上没有争议。但是你认为new Array(100)是无效的,这是不正确的。 - Már Örlygsson
11
请注意,new Array(1,2,3) 的结果是 [1,2,3],但 new Array(1) 的结果并不是 [1];因此,Array 的语义不一致且令人困惑。 - Dancrumb
4
我想补充一点,Object.create(null) 可以用于创建一个空对象,而 { } 则继承自 Object 原型。 - Meow
显示剩余10条评论

106

是的,它们有区别,它们不相同。虽然你会得到相同的结果,但引擎对它们的处理方式不同。其中一个是对象字面量,另一个则是构造函数,两种在JavaScript中创建对象的不同方法。

var objectA = {} //This is an object literal

var objectB = new Object() //This is the object constructor
在JS中,一切皆为对象,但你需要了解以下关于new Object()的事情:它可以接收一个参数,根据该参数的不同,它将创建一个字符串、一个数字或仅仅是一个空对象。
例如:new Object(1)将返回一个Number。new Object("hello")将返回一个字符串。这意味着对象构造函数可以根据参数委托给其他构造函数(如string、number等)来创建对象。当你管理动态数据以创建对象时,牢记这一点非常重要。
许多作者建议,在可以使用某种字面量符号的情况下,不要使用对象构造函数,因为这样你就能确保你所创建的是你在代码中期望得到的内容。
我建议你进一步阅读有关JavaScript字面量符号和构造函数之间差异的详细信息。

1
字面量表示法实际上更易读、更简洁,用于创建动态数据对象。 - Sid
非常注重细节的评论。你并不是为了代码而放置它,而是试图解释差异和重要的事情,即何时使用哪个语句。 谢谢! - Ali Hassan Cheema

14

这两种方法的最终结果相同,但我建议使用字面量语法,因为它可以帮助人们熟悉JSON的语法(一种JavaScript字面对象语法的字符串化子集),所以这可能是一个好习惯。

另外需要注意的是,如果忘记使用new运算符,可能会导致一些微妙的错误。因此,使用字面量可以避免这个问题。

最终,选择哪种方法取决于具体情况和个人偏好。


10
var objectA = {}

更快速,而且在我的经验中更常用,因此最好采用这个“标准”以节省打字时间。


1
更快运行还是更快打字? - hippietrail
好吧,不可否认,我是指“键入”,但考虑到额外的解析时间,执行方面可能会稍微更快一点 :-) - Bobby Jack
2
此外,字面量通常在解析时创建,而new Object必须在运行时执行。 - Phrogz

9

数组实例化性能

如果你想创建一个没有长度的数组:

var arr = [];var arr = new Array(); 更快。

如果你想创建一个特定长度的空数组:

var arr = new Array(x);var arr = []; arr[x-1] = undefined 更快。

点击以下链接查看基准测试: https://jsfiddle.net/basickarl/ktbbry5b/

然而,我不知道两者的内存占用情况,我可以想象new Array()占用更多的空间。


arr = new Array(x) 相当于 arr = []; arr.length = x;,而不是将 x-1 索引赋值为 undefined - Bergi

8

我相信在这里的Javascript视频中,{}被推荐为一种良好的编码规范。在伪经典继承中,new是必需的。使用var obj = {};可以帮助你记住它不是一个经典面向对象语言,而是一个原型式语言。因此,只有在使用构造函数时才真正需要new。例如:

var Mammal = function (name) {
  this.name = name;
};

Mammal.prototype.get_name = function () {
  return this.name;
}

Mammal.prototype.says = function() {
  return this.saying || '';
}

然后它可以这样使用:
var aMammal = new Mammal('Me warm-blooded');
var name = aMammal.get_name();

使用 {} 而不是 new Object 的另一个好处是可以使用它来创建 JSON 风格的对象字面量。

8
在JavaScript 1.2中引入了对象和数组字面量语法{}/[],因此在Netscape Navigator 4.0之前的版本中不可用(并且会产生语法错误)。
我的手指仍然默认使用new Array(),但我是一个非常老的人。幸运的是,今天很少有人需要考虑Netscape 3浏览器...

13
网景导航器3?天啊,那是在上个世纪!:-D - Tomalak
2
我得给这个答案吹一下灰尘,因为它太旧了! - basickarl

4
Var Obj = {};

这是最常用且最简单的方法。
使用
var Obj = new Obj() 

不建议使用new Object()

为了简单易读且执行速度更快,请使用第一个方法(对象字面量方法)。


这如何回答原始问题呢?“脚本引擎处理它们是否有任何区别?使用其中一个而不是另一个的原因是什么?” - Zsolt Meszaros
没有必要使用 new Object()。 为了简单、易读和执行速度,使用第一种方法(对象字面量方法)。 - Amit Singh

2

好的,只有两种不同的方法来完成同一件事情!其中一个叫做对象字面量,而另一个是一个构造函数

但请继续阅读,我想分享几件事情:

使用{}使您的代码更易读,而创建Object或其他内置函数的实例则不建议使用...

此外,Object函数作为函数获得参数,如Object(params)...但{}是在JavaScript中启动对象的纯方式...

在JavaScript中,使用对象字面量使您的代码看起来更加清晰易读,并且符合最佳实践...

虽然Javascript中的Object可以是任何东西,但{}仅指向Javascript对象,要测试它的工作原理,请在您的javascript代码或控制台中执行以下操作:

var n = new Object(1); //Number {[[PrimitiveValue]]: 1}

令人惊讶的是,它正在创建一个数字!

var a = new Object([1,2,3]); //[1, 2, 3]

这是创建一个数组!

var s = new Object('alireza'); //String {0: "a", 1: "l", 2: "i", 3: "r", 4: "e", 5: "z", 6: "a", length: 7, [[PrimitiveValue]]: "alireza"}

还有String的这个奇怪结果!

因此,如果您正在创建一个对象,建议使用对象字面量,以获得标准代码并避免以上类似的代码事故,从性能上来说,根据我的经验,使用{}更好!


你是伊朗的Dezfooli吗? - Ehsan
嗨Ehsan,是的,但我不住在伊朗,伙计,你在这里有一个很棒的个人资料!很高兴认识你... - Alireza
我能保存您的电话号码并向您寻求关于编程方面的帮助吗? - Ehsan
我看到你使用了 Telegram。 - Ehsan
是的,当然可以在 Telegram 上分享一些编程方面的知识!___ - Alireza
非常好,我现在给您发送一条消息,请保存我的号码。谢谢,阿里雷扎。 - Ehsan

2

这本质上是相同的事情。使用您发现更方便的任何内容。


也许我在深入研究JavaScript,但它们是一样的吗?Object的{proto}不是null,而{}的{proto}是'Object.prototype'吗? - Izhaki
@Izhaki Object 的原型是 null,这是正确的。这是因为 Object 终止了原型链。然而,Object实例没有原型,只有构造函数才有一个。并且 (new Object()).constructor === ({}).constructor -> true - Tomalak
那么,这个链接(http://zeekat.nl/articles/constructors-considered-mildly-confusing.html#sec-3-3)是不正确的吗? - Izhaki
这是我的观点:new Object() 会产生一个空的对象实例。{} 也会产生一个空的对象实例。这两个实例是完全无法区分的。你提供的示例做了其他事情(它修改了原型链),并且在这里并不适用 - 或者我没有理解你的论点。 - Tomalak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接