“new Object()”和对象字面量表示法有什么区别?
用于创建对象的基于构造函数的语法之间有什么区别:
person = new Object()
... 和文字语法:
person = {
property1 : "Hello"
};
看起来两者都执行相同的操作,尽管 JSLint 更喜欢使用对象文字表示法。
哪一个更好,为什么?
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.
Which one is better and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
对于您的示例中没有方法的简单对象来说没有什么区别。
但是,当您开始向对象添加方法时,就会出现很大的差异。
字面方式:
原型方式:
两种方式都允许创建
Obj
实例,如下所示:但是,使用字面方式,您可以在每个实例中携带
sayHello
方法的副本你的对象。而使用原型方式时,方法在对象原型中定义并在所有对象实例之间共享。如果你有很多对象或者很多方法,直接的方式可能会导致相当大的内存浪费。
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:
Prototype way:
Both ways allow creation of instances of
Obj
like this: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.
他们都做同样的事情(除非有人做了不寻常的事情),除了你的第二个创建一个对象并为其添加一个属性之外。但文字符号在源代码中占用的空间更少。可以清楚地识别正在发生的事情,因此使用 new Object(),您实际上只是输入更多内容并且(理论上,如果没有被 JavaScript 引擎优化的话)执行不必要的函数调用。
从技术上讲,这些
并没有做同样的事情。第一个只是创建一个对象。第二个创建一个并分配一个属性。为了使第一个相同,您需要第二步来创建和分配属性。
有人可以做的“不寻常的事情”是隐藏或分配给默认的全局对象:
在这种非常不寻常的情况下,新对象> 将失败,但
{}
可以工作。实际上,没有理由使用
new Object
而不是{}
(除非您做过那件非常不寻常的事情)。They both do the same thing (unless someone's done something unusual), other than that your second one creates an object and adds 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.These
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:In that highly-unusual case,
new Object
will fail but{}
will work.In practice, there's never a reason to use
new Object
rather than{}
(unless you've done that very unusual thing).在 JavaScript 中,我们可以通过两种方式声明一个新的空对象:
我没有发现任何迹象表明这两者在幕后操作方式上有任何显着差异(如果我错了,请纠正我 - 我很乐意知道)。然而,第二种方法(使用对象文字表示法)提供了一些优点。
考虑一个包含成员 Name 和 TelNo 的新对象。使用 new Object() 约定,我们可以像这样创建它:
Expando Properties JavaScript 功能允许我们以这种方式动态创建新成员,并且我们实现了预期目的。然而,这种方式不是很结构化或封装。如果我们想在创建时指定成员,而不必依赖扩展属性和创建后赋值,该怎么办?
这就是对象文字表示法可以提供帮助的地方:
在这里,我们用一行代码实现了相同的效果,并且字符数量明显减少。
对上述对象构造方法的进一步讨论可以在以下位置找到:JavaScript 和面向对象编程 (OOP)。
最后,那个覆盖 Object 的白痴怎么样了?你以为这不可能吗?好吧,这个 JSFiddle 证明了事实并非如此。使用对象字面量表示法可以防止我们陷入这种滑稽的行为。
(来自 http:// /www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)
In JavaScript, we can declare a new empty object in two ways:
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.
Consider a new object that contains the members Name and TelNo. Using the new Object() convention, we can create it like this:
The Expando Properties feature 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?
This is where the object literal notation can help:
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).
And finally, what of the idiot who overrode Object? Did you think it wasn’t possible? Well, this JSFiddle proves otherwise. Using the object literal notation prevents us from falling foul of this buffoonery.
(From http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)
在使用 Node.js 的计算机上,我运行了以下命令:
注意,这是此处找到的内容的扩展: 为什么 arr = [] 比 arr = new Array 更快?
我的输出如下:
显然 {} 和 [] 比使用 new 创建空对象/数组更快。
On my machine using Node.js, I ran the following:
Note, this is an extension of what is found here: Why is arr = [] faster than arr = new Array?
my output was the following:
so clearly {} and [] are faster than using new for creating empty objects/arrays.
这里的每个人都在谈论两者的相似之处。我会指出其中的差异。
使用
new Object()
允许您传递另一个对象。明显的结果是新创建的对象将被设置为相同的引用。这是示例代码:其用法并不限于 OOP 对象中的对象。其他类型也可以传递给它。该函数将相应地设置类型。例如,如果我们将整数 1 传递给它,则会为我们创建一个 number 类型的对象。
如果向使用上述方法(
new Object(1)
)创建的对象添加属性,则该对象将转换为对象类型。如果对象是对象子类的副本,我们可以添加属性而不进行类型转换。
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: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.
The object created using the above method (
new Object(1)
) would be converted to object type if a property is added to it.If the object is a copy of a child class of object, we could add the property without the type conversion.
实际上,在 JavaScript 中创建对象的方法有多种。当您只想创建一个对象时,使用“new”运算符创建“基于构造函数的”对象没有任何好处。它与使用“对象文字”语法创建对象相同。但是,当您考虑“原型继承”时,使用“new”运算符创建的“基于构造函数的”对象会发挥令人难以置信的作用。您无法使用使用文字语法创建的对象来维护继承链。但是您可以创建一个构造函数,将属性和方法附加到其原型。然后,如果您使用“new”运算符将此构造函数分配给任何变量,它将返回一个对象,该对象将有权访问该构造函数原型所附加的所有方法和属性。
下面是使用构造函数创建对象的示例(请参阅底部的代码说明):
现在,您可以通过实例化 Person 构造函数来创建任意多个对象,并且所有对象都将从它继承 fullname() 。
笔记:
“this”关键字将引用构造函数中的空对象,每当您使用“new”运算符从 Person 创建新对象时,它都会自动返回一个包含所有内容的对象附加“this”关键字的属性和方法。这些对象肯定会继承 Person 构造函数的 prototype 所附加的方法和属性(这是这种方法的主要优点)。
顺便说一句,如果您想使用“对象文字”语法获得相同的功能,则必须在所有对象上创建 fullname() ,如下所示:
最后,如果您现在问为什么我应该使用构造函数方法而不是对象文字方法:
*** 原型继承允许简单的继承链,这非常有用和强大。
*** 它通过继承构造函数原型中定义的常用方法和属性来节省内存。否则,您将不得不在所有对象中一遍又一遍地复制它们。
我希望这是有道理的。
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.
Here is an example of creating an object using constructor function (see code explanation at the bottom):
Now, you can create as many objects as you want by instantiating Person construction function and all of them will inherit fullname() from it.
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 prototype of the Person constructor function (which is the main advantage of this approach).
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:
At last, if you now ask why should I use constructor function approach instead of object literal approach:
*** 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.
另外,根据一些 O'Really javascript 书籍......(引用)
使用文字而不是对象构造函数的另一个原因是没有范围解析。因为您可能创建了一个同名的本地构造函数,所以解释器需要从您调用 Object() 的位置一直查找作用域链,直到找到全局 Object 构造函数。
Also, according to some of the O'Really javascript books....(quoted)
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.
2019 更新
我在 OSX High Sierra 10.13.6 节点版本 10.13.0 上运行了与 @rjloura 相同的代码,这些是结果
2019 Update
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
我发现了 ES6/ES2015 的一个区别。不能使用简写箭头函数语法返回对象,除非用
new Object()
包围该对象。这是因为编译器对
{}
括号感到困惑,并认为n: i
是 标签:声明 构造;分号是可选的,所以它不会抱怨它。如果向对象添加另一个属性,它最终会抛出错误。
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()
.This is because the compiler is confused by the
{}
brackets and thinksn: i
is a label: statement construct; the semicolon is optional so it doesn't complain about it.If you add another property to the object it will finally throw an error.
我唯一一次使用“new”关键字进行对象初始化是在内联箭头函数中:
因为以下代码无效:
The only time i will use the 'new' keyowrd for object initialization is in inline arrow function:
since the below code is not valid:
这里有很多很好的答案,但我想拿出我的 50 美分。
所有这些答案都缺少一个简单的类比,这个类比对于刚刚开始编程语言之旅的人来说是有效的。
希望我能用这个类比来填补这个空白:
对象文字创建与基于构造函数的语法
感受句子创建的区别。
如果我有一句话
“我喜欢奶酪”
,我可以清楚而大声地告诉你(字面意思或逐字):我喜欢奶酪。这是我按字面(逐字)创造的句子。
所有其他方法都是一些棘手的方法,可以让您准确地理解我创建的句子。例如,我告诉你:
“I”
,宾语是“cheese”
,谓语是“to like”
。这是您毫无歧义地学习同一句话的另一种方式:“我喜欢奶酪”。
或者,
在这种情况下,你也会得到相同的结果:你确切地知道这句话是什么。
您可以设计与“逐字”句子创建(LITERAL)不同的任何其他方法,以及间接(非字面、非逐字)句子创建方法。
我认为这就是这里的核心概念。
There are a lot of great answers here, but I want to come with my 50 cents.
What all of these answers are missing is a simple analogy which would work for a person who just starts his journey in the programming languages.
Hopefully, I will fill this gap with this analogy:
Object Literal Creation vs Constructor-based Syntax
Feel the difference with a sentence creation.
If I have a sentence
"I like cheese"
, I can tell you clearly and loudly (literally, or verbatim): I like cheese.This is my literal (word by word) creation of the sentence.
All other ways are some tricky ways of making you to understand of what sentence I created exactly. For example, I tell you:
"I"
, the object is"cheese"
, and the predicate is"to like"
.This is another way of YOU to learn without any ambiguities the very same sentence: "I like cheese".
Or,
In this case, you also come to the same result: you know exactly what the sentence is.
You can devise any other methods which would differ from "word-by-word" sentence creation (LITERAL), and which would be INDIRECT (non literal, non verbatim) method of sentence creation.
I think this is the core concept which lays here.
如果我们尝试测量对象创建像这样 (替代链接):
这会给你非常有趣的结果:
你可以看到,当我们执行多次>=100时,
对象文字
比new MyObject()
慢。这种差异可以通过以下事实来解释:对象字面量消耗更多的内存和 CPU 来初始化每个对象唯一的
foo()
方法,而 MyObject 类共享单个foo()
通过原型及其所有实例。然而,当我们从测试中删除该方法时:
然后我们可以看到差异几乎消失了(基准):
If we will try to measure objects creation like this (alternative link):
Which will give you very interesting result:
You can see that the
object literal
is slower thannew MyObject()
when we do it multiple times >=100.This difference can be explained by the fact that object literal consumes much more memory and CPU to initialize
foo()
method which is unique for each object, while the MyObject class shares a singlefoo()
with all of its instances through the prototype.However, when we remove the method from the test:
Then we can see that the difference almost disappears (benchmark):
如果创建 10000 个实例,内存使用情况会有所不同。
new Object()
将仅保留一份副本,而{}
将保留 10,000 个副本。Memory usage is different if you create 10 thousand instances.
new Object()
will only keep only one copy while{}
will keep 10 thousand copies.