JavaScript中的“new”只是“.call”的语法糖吗?

JavaScript中的“new”只是“.call”的语法糖吗?,javascript,Javascript,在JavaScript中,我想知道new是否有什么特别之处,或者它是否只是call()的语法糖。如果我有一个构造函数,比如: function Person ( name, age ){ this.name = name; this.age = age; } 是 有什么不同于 var bob; Person.call( bob = new Object(), "Bob", 55 ); 不,new不仅仅是语法上的糖分。相反,Person.call可以(并且只可以)构造一个新实例

在JavaScript中,我想知道
new
是否有什么特别之处,或者它是否只是
call()
的语法糖。如果我有一个构造函数,比如:

function Person ( name, age ){
    this.name = name;
    this.age = age;
}

有什么不同于

var bob;
Person.call( bob = new Object(), "Bob", 55 );

不,
new
不仅仅是语法上的糖分。相反,
Person.call
可以(并且只可以)构造一个新实例,因为

否。

call()
仅调用函数(另请参见
apply()
),而
new
关键字从原型初始化对象


虽然原型构造函数确实是一个函数,但它是一个特例。

不,它不是。如果你的第一个例子,你实际上是在创造一个人

bob instanceof Person == true
在另一个例子中

bob instanceof Person == false

创建类型实例的目的是共享一些行为,通常是通过原型

假设您添加了一个函数:

Person.prototype.doSomething = function(){
   ...
}
然后,此功能将可用于使用
new
创建为
Person
实例的所有对象,但不适用于使用
call
创建的对象


MDN有一个.

当您调用
new
时,您将作为构造函数调用该函数。这告诉JavaScript创建一个“新的”
Person
对象,然后将该新对象设置为
This
调用函数

在第二个示例中,您正在正常调用函数,并手动将
this
设置为
新对象(或仅
{}
)。因此,函数运行,并设置发送它的
对象的属性。(试着只做
Person(“Bob”,55);
,然后再做
console.log(window.name)

在第一个示例中,
bob
Person
对象;但在第二种情况下,它是一个
对象


所以,不,一个不是另一个的缩写。它们是不同的。

在您的示例中,它们不是等价的,因为
bob
不继承自
Person.prototype
(它直接继承自
Object.prototype

同样的版本是

Person.call(bob = Object.create(Person.prototype), "Bob", 55 );
是糖吗?可能取决于您如何定义它

Object.create
在早期的JS版本中不可用,因此在没有
new
的情况下无法设置对象继承(您可以在某些浏览器中覆盖对象的属性,但这是非常糟糕的做法)



作为参考,和中定义了
new
的工作原理<代码>对象.create
如中所述。

它们不是等价的,等价的版本将是
Person.call(bob=Object.create(Person.prototype),“bob”,55)。是糖吗?可能取决于您如何定义它
Object.create
在早期的JS版本中不可用。@FelixKling可能应该回答这个问题而不是评论,这是一个很好的答案。:)
Person.call(bob = Object.create(Person.prototype), "Bob", 55 );