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

person = new Object()

...这个文字语法:

person = {
    property1 : "Hello"
};

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

哪个更好,为什么?


当前回答

如果您创建10,000个实例,内存使用情况将有所不同。 new Object()将只保留一个副本,而{}将保留10,000个副本。

其他回答

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.

下面是一个使用构造函数创建对象的例子(参见底部的代码说明):

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();

现在,您可以通过实例化Person构造函数创建任意多的对象,所有这些对象都将从它继承fullname()。

注意: “this”关键字将引用构造函数中的一个空对象,每当您使用“new”操作符从Person创建一个新对象时,它将自动返回一个包含所有属性和方法的对象,并附加“this”关键字。而且这些对象肯定会继承Person构造函数原型附带的方法和属性(这是这种方法的主要优点)。

顺便说一下,如果你想用“对象文字”语法获得相同的功能,你必须在所有对象上创建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();

最后,如果你现在问我为什么要使用构造函数方法而不是对象文字方法:

原型继承允许一个简单的继承链,这是非常有用和强大的。

***通过继承构造函数原型中定义的通用方法和属性来节省内存。否则,你必须在所有对象中一遍又一遍地复制它们。

我希望这是有意义的。

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

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

这里有很多很好的答案,但我想用我的50美分来回答。

所有这些答案所缺少的是一个简单的类比,它适用于刚开始学习编程语言的人。

希望我能用这个类比来填补这个空白:

对象文字创建vs基于构造函数的语法

感受句子创作的不同之处。

如果我有一句话“我喜欢奶酪”,我可以清楚响亮地(字面上,或逐字逐句地)告诉你:我喜欢奶酪。

这是我逐字逐句创造的句子。

所有其他的方法都是一些棘手的方法来让你理解我到底创造了什么句子。例如,我告诉你:

在我的句子中,主语是“I”,宾语是“cheese”,谓词是“to like”。 这是你学习同一句话的另一种方式,没有任何歧义:“我喜欢奶酪”。

Or,

我的句子有3个单词:第一个是英语字典里的第n个单词,第二个是英语字典里的第m个单词,最后一个是英语字典里的第l个单词。

在这种情况下,你也会得到同样的结果:你确切地知道这句话是什么。

你可以设计任何其他方法,这将不同于“逐字”的句子创建(字面),这将是间接(非字面,非逐字)的句子创建方法。

我认为这是这里的核心概念。

我发现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 :

它们都做同样的事情(除非有人做了不寻常的事情),除了第二个创建一个对象并向其添加一个属性。但是文字符号在源代码中占用的空间更少。可以清楚地看出发生了什么,因此使用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而不是{}(除非您做了非常不寻常的事情)。