Javascript `new Object()` 和对象文字符号有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4597926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between `new Object()` and object literal notation?
提问by ectype
What is the difference between this constructor-based syntax for creating an object:
这种用于创建对象的基于构造函数的语法有什么区别:
person = new Object()
...and this literal syntax:
...还有这个字面语法:
person = {
property1 : "Hello"
};
It appears that both do the same thing, although JSLint prefers you use object literal notation.
看起来两者都做同样的事情,尽管 JSLint 更喜欢您使用对象文字表示法。
Which one is better and why?
哪个更好,为什么?
采纳答案by kemiller2002
They both do the same thing (unless someone's done something unusual), other than that your second one creates an object andadds a property to it. But literal notation takes less space in the source code. It's clearly recognizable as to what is happening, so using new Object()
, you are really just typing more and (in theory, if not optimized out by the JavaScript engine) doing an unnecessary function call.
他们都做同样的事情(除非某人的做了一些不寻常的),比其他的第二个创建一个对象,并增加了一个属性它。但是文字符号在源代码中占用的空间更少。可以清楚地识别正在发生的事情,因此使用new Object()
,您实际上只是输入更多并且(理论上,如果没有被 JavaScript 引擎优化)执行不必要的函数调用。
These
这些
person = new Object() /*You should put a semicolon here too.
It's not required, but it is good practice.*/
-or-
person = {
property1 : "Hello"
};
technically do not do the same thing. The first just creates an object. The second creates one and assigns a property. For the first one to be the same you then need a second step to create and assign the property.
从技术上讲,不要做同样的事情。第一个只是创建一个对象。第二个创建一个并分配一个属性。对于第一个相同的,您需要第二个步骤来创建和分配属性。
The "something unusual" that someone could do would be to shadow or assign to the default Object
global:
有人可以做的“不寻常的事情”是隐藏或分配给默认Object
全局:
// Don't do this
Object = 23;
In that highly-unusualcase, new Object
will fail but {}
will work.
在这种非常不寻常的情况下,new Object
会失败但{}
会起作用。
In practice, there's never a reason to use new Object
rather than {}
(unless you've done that very unusual thing).
在实践中,从来没有理由使用new Object
而不是{}
(除非你做了那件非常不寻常的事情)。
回答by Rémy DAVID
There is no difference for a simple object without methods as in your example. However, there is a big difference when you start adding methods to your object.
与您的示例中一样,没有方法的简单对象没有区别。但是,当您开始向对象添加方法时,会有很大的不同。
Literal way:
字面方式:
function Obj( prop ) {
return {
p : prop,
sayHello : function(){ alert(this.p); },
};
}
Prototype way:
原型方式:
function Obj( prop ) {
this.p = prop;
}
Obj.prototype.sayHello = function(){alert(this.p);};
Both ways allow creation of instances of Obj
like this:
这两种方式都允许创建这样的实例Obj
:
var foo = new Obj( "hello" );
However, with the literal way, you carry a copy of the sayHello
method within each instance of your objects. Whereas, with the prototype way, the method is defined in the object prototype and shared between all object instances.
If you have a lot of objects or a lot of methods, the literal way can lead to quite big memory waste.
但是,通过字面方式,您可以sayHello
在对象的每个实例中携带该方法的副本。而在原型方式中,方法是在对象原型中定义的,并在所有对象实例之间共享。
如果你有很多对象或很多方法,字面方式会导致相当大的内存浪费。
回答by James Wiseman
In JavaScript, we can declare a new empty object in two ways:
在 JavaScript 中,我们可以通过两种方式声明一个新的空对象:
var obj1 = new Object();
var obj2 = {};
I have found nothing to suggest that there is any significant difference these two with regard to how they operate behind the scenes (please correct me if i am wrong – I would love to know). However, the second method (using the object literal notation) offers a few advantages.
我没有发现任何迹象表明这两者在幕后运作方面存在任何显着差异(如果我错了,请纠正我 - 我很想知道)。然而,第二种方法(使用对象字面量表示法)提供了一些优点。
- It is shorter (10 characters to be precise)
- It is easier, and more structured to create objects on the fly
- It doesn't matter if some buffoon has inadvertently overridden Object
- 它更短(准确地说是 10 个字符)
- 动态创建对象更容易、更有条理
- 如果某个小丑无意中覆盖了 Object 并不重要
Consider a new object that contains the members Name and TelNo. Using the new Object() convention, we can create it like this:
考虑一个包含成员 Name 和 TelNo 的新对象。使用 new Object() 约定,我们可以像这样创建它:
var obj1 = new Object();
obj1.Name = "A Person";
obj1.TelNo = "12345";
The Expando Propertiesfeature of JavaScript allows us to create new members this way on the fly, and we achieve what were intending. However, this way isn't very structured or encapsulated. What if we wanted to specify the members upon creation, without having to rely on expando properties and assignment post-creation?
JavaScript的Expando 属性功能允许我们以这种方式动态创建新成员,并且我们实现了预期目的。但是,这种方式不是很结构化或封装。如果我们想在创建时指定成员,而不必依赖于 expando 属性和创建后分配怎么办?
This is where the object literal notation can help:
这是对象文字符号可以提供帮助的地方:
var obj1 = {Name:"A Person",TelNo="12345"};
Here we have achieved the same effect in one line of code and significantly fewer characters.
在这里,我们用一行代码实现了同样的效果,而且字符明显减少了。
A further discussion the object construction methods above can be found at: JavaScript and Object Oriented Programming (OOP).
可以在以下位置找到对上述对象构造方法的进一步讨论:JavaScript 和面向对象编程 (OOP)。
And finally, what of the idiot who overrode Object? Did you think it wasn't possible? Well, this JSFiddleproves otherwise. Using the object literal notation prevents us from falling foul of this buffoonery.
最后,那个凌驾于 Object 的白痴呢?你以为不可能吗?好吧,这个 JSFiddle证明并非如此。使用对象字面量表示法可以防止我们对这种小丑恶作剧犯规。
(From http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)
(来自http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)
回答by rjloura
On my machine using Node.js, I ran the following:
在我使用 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');
Note, this is an extension of what is found here: Why is arr = [] faster than arr = new Array?
请注意,这是此处内容的扩展:为什么 arr = [] 比 arr = new Array 快?
my output was the following:
我的输出如下:
Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms
so clearly {} and [] are faster than using new for creating empty objects/arrays.
很明显 {} 和 [] 比使用 new 创建空对象/数组更快。
回答by Jermin Bazazian
Everyone here is talking about the similarities of the two. I am gonna point out the differences.
这里的每个人都在谈论两者的相似之处。我要指出不同之处。
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
Using
new Object()
允许您传递另一个对象。显而易见的结果是新创建的对象将被设置为相同的引用。这是一个示例代码:var obj1 = new Object(); obj1.a = 1; var obj2 = new Object(obj1); obj2.a // 1
用法不限于 OOP 对象中的对象。其他类型也可以传递给它。该函数将相应地设置类型。例如,如果我们将整数 1 传递给它,则会为我们创建一个类型为 number 的对象。
var obj = new Object(1); typeof obj // "number"
new Object(1)
如果向其添加属性,则使用上述方法 ( )创建的对象将转换为对象类型。var obj = new Object(1); typeof obj // "number" obj.a = 2; typeof obj // "object"
如果对象是对象子类的副本,我们可以在不进行类型转换的情况下添加属性。
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
回答by Md. Zubaer Ahammed
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.
实际上,在 JavaScript 中有多种创建对象的方法。当您只想创建一个对象时,使用“ new”运算符创建“基于构造函数”的对象没有任何好处。这与使用“对象字面量”语法创建对象相同。但是,当您考虑“原型继承”时,使用“ new”运算符创建的“基于构造函数”的对象会变得非常有用。您不能使用用文字语法创建的对象来维护继承链。但是你可以创建一个构造函数,将属性和方法附加到它的原型上。" 运算符,它将返回一个对象,该对象可以访问与该构造函数的原型相关联的所有方法和属性。
Here is an example of creating an object using constructor function (see code explanation at the bottom):
下面是一个使用构造函数创建对象的例子(见底部的代码解释):
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();
Now, you can create as many objects as you want by instantiating Person construction function and all of them will inherit fullname() from it.
现在,您可以通过实例化 Person 构造函数来创建任意数量的对象,并且所有对象都将从它继承 fullname() 。
Note: "this" keyword will refer to an empty object within a constructor function and whenever you create a new object from Person using "new" operator it will automatically return an object containing all of the properties and methods attached with the "this" keyword. And these object will for sure inherit the methods and properties attached with the prototypeof the Person constructor function (which is the main advantage of this approach).
注意:“ this”关键字将在构造函数中引用一个空对象,每当您使用“ new”操作符从 Person 创建一个新对象时,它将自动返回一个对象,其中包含所有附加到“ this”关键字的属性和方法. 并且这些对象肯定会继承与Person 构造函数的原型相关的方法和属性(这是这种方法的主要优点)。
By the way, if you wanted to obtain the same functionality with "object literal" syntax, you would have to create fullname() on all of the objects like below:
顺便说一句,如果您想使用“对象文字”语法获得相同的功能,则必须在所有对象上创建 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();
At last, if you now ask why should I use constructor functionapproach instead of object literalapproach:
最后,如果你现在问我为什么要使用构造函数方法而不是对象字面量方法:
*** Prototypal inheritance allows a simple chain of inheritance which can be immensely useful and powerful.
*** 原型继承允许一个简单的继承链,它非常有用和强大。
*** It saves memory by inheriting common methods and properties defined in constructor functions prototype. Otherwise, you would have to copy them over and over again in all of the objects.
*** 它通过继承构造函数原型中定义的常用方法和属性来节省内存。否则,您将不得不在所有对象中一遍又一遍地复制它们。
I hope this makes sense.
我希望这是有道理的。
回答by adolfo_isassi
Also, according to some of the O'Really javascript books....(quoted)
另外,根据一些 O'Really javascript 书籍....(引用)
Another reason for using literals as opposed to the Object constructor is that there is no scope resolution. Because it's possible that you have created a local constructor with the same name, the interpreter needs to look up the scope chain from the place you are calling Object() all the way up until it finds the global Object constructor.
使用文字而不是 Object 构造函数的另一个原因是没有范围解析。因为您可能创建了一个同名的本地构造函数,解释器需要从您调用 Object() 的位置一直向上查找作用域链,直到找到全局 Object 构造函数。
回答by Andrei Simionescu
I have found one difference, for ES6/ES2015. You cannot return an object using the shorthand arrow function syntax, unless you surround the object with new Object()
.
我发现了 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 } ]
This is because the compiler is confused by the {}
brackets and thinks n: i
is a label: statementconstruct; the semicolon is optional so it doesn't complain about it.
这是因为编译器被{}
括号混淆了,认为n: i
是一个标签:语句构造;分号是可选的,所以它不会抱怨它。
If you add another property to the object it will finally throw an error.
如果向对象添加另一个属性,它最终会抛出错误。
$ 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 :
回答by PirateApp
2019 Update
2019年更新
I ran the same code as @rjloura on my OSX High Sierra 10.13.6 node version 10.13.0 and these are the results
我在 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
回答by Richard Miao US
Memory usage is different if you create 10 thousand instances.
new Object()
will only keep only one copy while {}
will keep 10 thousand copies.
如果创建 1 万个实例,内存使用情况会有所不同。
new Object()
只会保留一份,而{}
将保留一万份。