`new Object()` 和对象文字符号有什么区别?

IT技术 javascript object jslint
2021-01-26 00:42:16

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

person = new Object()

...还有这个字面语法:

person = {
    property1 : "Hello"
};

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

哪个更好,为什么?

6个回答

与您的示例中一样,没有方法的简单对象没有区别。但是,当您开始向对象添加方法时,会有很大的不同。

字面方式:

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在对象的每个实例中携带该方法的副本而在原型方式中,方法是在对象原型中定义的,并在所有对象实例之间共享。 如果你有很多对象或很多方法,字面方式会导致相当大的内存浪费。

当我发布这个时,接受的答案已经存在并被接受。它完美地回答了 OP 问题,所以我不会重复同样的事情。我发布我的答案主要是为了将主题扩展到空的/简单的对象之外。在这种情况下,有其中值得一提的一个重要区别。
2021-03-15 00:42:16
对我来说,问题更多是关于使用new Object()vs{}创建空对象之间的差异
2021-03-20 00:42:16
这个答案是题外话。在您的代码中,Obj 是从 Object 继承的单独类。当您使用对象字面量表示法时,您使用的是 Object 类,而不是 Obj。当然,在其原型中设置一个带有方法的类将使内存占用比创建大量普通对象并添加方法作为它们的属性要小,但这与这里提出的问题完全无关。这个问题的正确答案是“不,绝对没有区别(可能除了可读性)”。
2021-03-25 00:42:16
我是根据一个有点像我的问题来寻求这个答案的,但最终我完全了解了我需要知道的内容。谢谢你。
2021-04-06 00:42:16
@Lobabob 除了第一句话外,这个答案实际上并未提供有关 OP 问题的任何信息。它甚至在任何地方都不包含“new Object()”。坦率地说,我认为大卫先生误解了这个问题。
2021-04-09 00:42:16

他们都做同样的事情(除非某人的做了一些不寻常的),比其他的第二个创建一个对象,并增加了一个属性它。但是文字符号在源代码中占用的空间更少。可以清楚地识别正在发生的事情,因此使用new Object(),您实际上只是输入更多并且(理论上,如果没有被 JavaScript 引擎优化)执行不必要的函数调用。

这些

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

从技术上讲,不要做同样的事情。第一个只是创建一个对象。第二个创建一个并分配一个属性。对于第一个相同的,您需要第二个步骤来创建和分配属性。

有人可以做的“不寻常的事情”是隐藏或分配给默认Object全局:

// Don't do this
Object = 23;

在这种非常不寻常的情况下,new Object会失败但{}会起作用。

在实践中,从来没有理由使用new Object而不是{}(除非你做了那件非常不寻常的事情)。

我认为我们不需要使用new作为当前规范。让我知道你的想法@kevin
2021-03-13 00:42:16
仅供参考也不() new Object()是必需的。(谈论不需要的东西)
2021-03-14 00:42:16
作者选择这个答案是正确的,但它是不完整的。当您进入内存分配时,请注意这两种语法之间存在差异。
2021-03-17 00:42:16
如果您想要一个不从继承链继承的对象,您也可以使用 Object create 并传递 null 。它们不相等,分别具有有用的目的。
2021-03-17 00:42:16
没有区别。如果您指的是下面的答案之一,则它是题外话,因为它在谈论基于原型的对象模型和继承(那里的代码设置了一个从普通对象继承的 Obj 类)。这个问题不是关于创建某个自定义类的实例——而是关于创建 Object 的实例,这个问题的正确答案是“没有区别”。
2021-03-26 00:42:16

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

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

我没有发现任何迹象表明这两者在幕后运作方面存在任何显着差异(如果我错了,请纠正我 - 我很想知道)。然而,第二种方法(使用对象字面量表示法)提供了一些优点。

  1. 它更短(准确地说是 10 个字符)
  2. 动态创建对象更容易、更有条理
  3. 如果某个小丑无意中覆盖了 Object 并不重要

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

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

JavaScriptExpando 属性功能允许我们以这种方式动态创建新成员,并且我们实现了预期目的。但是,这种方式不是很结构化或封装。如果我们想在创建时指定成员,而不必依赖于 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/

2021-03-29 00:42:16
如果new Object()由于某些东西可能会覆盖 Object 函数而偏爱对象字面量,那么当您使用帮助器Object.keys来确保它不是 undefined时,您还应该到处写守卫,这会导致荒谬。我总是建议人们使用字面表示法,但我认为当你想到那样思考的后果时,这个特殊的论点就站不住脚了。
2021-03-30 00:42:16
语法错误:意外的标记“=”。应在属性名称“TelNo”后面有一个“:”。
2021-03-31 00:42:16

在我使用 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');

请注意,这是此处内容的扩展:为什么 arr = [] 比 arr = new Array 快?

我的输出如下:

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

很明显 {} 和 [] 比使用 new 创建空对象/数组更快。

我觉得这就是问题真正要寻找的答案,尽管我希望在具有一些属性的对象上进行额外测试以确保。
2021-03-14 00:42:16
在 Node 10.13.0 上,测试数组发生了变化:using[]: 117.178ms using new: 116.947ms 测试对象:using{}: 116.252ms using new: 115.910ms
2021-03-15 00:42:16
有趣的数字。有些人需要意识到这一点,但我认为即使分配微薄的 200,000 个对象也只会花费我 5.6 毫秒,所以我不会担心。
2021-03-27 00:42:16

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

  1. Usingnew Object()允许您传递另一个对象。显而易见的结果是新创建的对象将被设置为相同的引用。这是一个示例代码:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
    
  2. 用法不限于 OOP 对象中的对象。其他类型也可以传递给它。该函数将相应地设置类型。例如,如果我们将整数 1 传递给它,则会为我们创建一个类型为 number 的对象。

    var obj = new Object(1);
    typeof obj // "number"
    
  3. new Object(1)如果向其添加属性,则使用上述方法 ( )创建的对象将转换为对象类型。

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
    
  4. 如果对象是对象子类的副本,我们可以在不进行类型转换的情况下添加属性。

    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
    
@AndreaScarafoni 因为str是类型,string所以您不能为其分配属性。jsfiddle.net/grq6hdx7/1
2021-03-15 00:42:16
我对最后两行很困惑..为什么如果你给 str.a 赋值 1,str.a 是未定义的?.. @Jermin Bazazin
2021-03-19 00:42:16
4的答案有变化吗?在最新的 Chrome 53 中,我得到了错误的信息 var obj = new Object("foo"); typeof obj; obj === "foo" // true
2021-04-10 00:42:16