在JavaScript中,我想知道new
是否有什么特别之处,或者它是call()
的语法糖。如果我有一个像:
function Person ( name, age ){
this.name = name;
this.age = age;
}
是
var bob = new Person( "Bob", 55 );
与
不同var bob;
Person.call( bob = new Object(), "Bob", 55 );
答案 0 :(得分:3)
它们在您的示例中不相同,因为bob
不会从Person.prototype
继承(它直接继承自Object.prototype
)。
等效版本将是
Person.call(bob = Object.create(Person.prototype), "Bob", 55 );
是语法糖吗?可能取决于您如何定义它。
早期的JS版本中没有 Object.create
,因此在没有new
的情况下无法设置对象继承(您可以在某些浏览器中覆盖对象的internal __proto__
property ,但那是非常不好的做法。)
作为参考,new
和http://es5.github.com/#x11.2.2定义了Object.create
的工作原理。 http://es5.github.com/#x13.2.2中描述了{{1}}。
答案 1 :(得分:2)
不,new
不是只是语法糖。相反,Person.call
可以(并且只能工作)构建新实例,因为JavaScript allows constructors to be called without new
in some cases.
答案 2 :(得分:2)
否。
call()
只调用一个函数(另请参阅apply()
),而new
关键字初始化一个原型中的对象。
虽然原型构造函数是一个函数,但它是一个特例。
答案 3 :(得分:2)
不,不是。如果是第一个例子,那么您实际上是在创建一个Person。
bob instanceof Person == true
在另一个例子中......
bob instanceof Person == false
答案 4 :(得分:1)
创建类型实例的目的是分享一些行为,通常是通过原型。
假设您添加了一个函数:
Person.prototype.doSomething = function(){
...
}
然后,此功能可用于使用Person
作为new
实例创建的所有对象,但不能用于使用call
创建的对象。
MDN有good introductory document about the use of the prototype。
答案 5 :(得分:1)
当您调用new
时,您将该函数作为构造函数调用。这告诉JavaScript,创建一个“新的”Person
对象,然后使用设置为this
的新对象调用该函数。
在第二个示例中,您正在正常调用该函数,并手动将this
设置为new Object
(或仅{}
)。因此,该函数运行,并设置您发送它的this
对象的属性。 (尝试执行Person( "Bob", 55 );
,然后console.log(window.name)
)
在第一个示例中,bob
是Person
个对象;但在第二天,它是Object
。
所以,不,一个人对另一个人来说并不缺乏。他们是不同的。