“ new Object()”和对象文字符号之间有什么区别?

2020/10/16 18:21 · javascript ·  · 0评论

创建对象的基于构造函数的语法之间有什么区别:

person = new Object()

...以及这种文字语法:

person = {
    property1 : "Hello"
};

尽管JSLint偏爱您使用对象文字表示法,但两者似乎都做相同的事情。

哪一个更好,为什么?

除了您的第二个对象创建对象并向其添加属性之外,它们都执行相同的操作(除非某人做了不寻常的操作)但是文字表示法在源代码中占用的空间更少。可以很清楚地知道发生了什么,因此使用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而不是{}(除非您已经完成了非常不寻常的事情)。

像您的示例中那样,没有方法的简单对象没有什么区别。但是,开始向对象添加方法时有很大的不同。

文字方式:

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

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

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

我发现没有什么迹象表明这两者在幕后的运作方式上有任何显着差异(如果我错了,请纠正我,我很想知道)。但是,第二种方法(使用对象文字表示法)具有一些优点。

  1. 较短(精确到10个字符)
  2. 可以更轻松,更结构化地动态创建对象
  3. 某个丑角是否意外覆盖了对象无关紧要

考虑一个包含成员Name和TelNo的新对象。使用新的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/

在使用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创建空对象/数组要快。

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

  1. 使用new 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
    

实际上,有几种方法可以用JavaScript创建对象。当您只想创建一个对象时,使用“ new ”运算符创建基于基于构造函数的”对象没有任何好处这与使用“对象文字”语法创建对象相同但是,当您考虑“原型继承时,使用new ”运算符创建的“基于构造函数”的对象将得到不可思议的使用您不能维护使用文字语法创建的对象的继承链。但是您可以创建一个构造函数,将属性和方法附加到其原型。”运算符,它将返回一个对象,该对象可以访问该构造函数的原型附带的所有方法和属性。

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

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

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:

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

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

***原型继承允许简单的继承链,这可能非常有用和强大。

***它通过继承构造函数实例中定义的通用方法和属性来节省内存。否则,您将不得不在所有对象中一遍又一遍地复制它们。

我希望这是有道理的。

另外,根据O'Really的一些javascript书籍。...(引用)

使用文字而不是对象构造函数的另一个原因是没有范围解析。因为可能已经创建了一个具有相同名称的本地构造函数,所以解释器需要从您一直调用Object()的位置一直查找范围链,直到找到全局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 } ]

这是因为编译器被{}方括号弄糊涂了,并认为它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 :

2019更新

我在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

我唯一使用“ new”键初始化对象的方法是内联箭头功能:

() => new Object({ key: value})

由于以下代码无效:

() => { key: value} //  instead of () => { return { key: value};}

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

本文地址:http://javascript.askforanswer.com/new-objectheduixiangwenzifuhaozhijianyoushenmequbie.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!