繁体   English   中英

JavaScript中的`new`只是`.call`的语法糖?

[英]Is `new` in JavaScript just syntactic sugar for `.call`?

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

它们在您的示例中不等效,因为bob不从Person.prototype继承(它直接从Object.prototype继承)。

等效版本将是

Person.call(bob = Object.create(Person.prototype), "Bob", 55 );

是语法糖吗? 可能取决于您如何定义它。

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


作为参考,如何在http://es5.github.com/#x11.2.2http://es5.github.com/#x13.2.2中定义new工作。 Object.createhttp://es5.github.com/#x15.2.3.5中描述。

不, new不仅仅是语法糖。 相反, Person.call可以(并且只能工作)构造一个新实例,因为JavaScript允许在某些情况下调用构造函数而不使用new

没有。

call()只调用一个函数(另请参见apply() ),而new关键字初始化一个原型的对象。

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

不,这不对。 如果是第一个例子,那么您实际上是在创建一个Person。

bob instanceof Person == true

在另一个例子中......

bob instanceof Person == false

创建类型实例的关键是分享一些行为,通常是通过原型。

假设您添加了一个函数:

Person.prototype.doSomething = function(){
   ...
}

然后,此函数将可用于使用new创建的Person实例的所有对象,但不能用于使用call创建的对象。

MDN有一个关于原型使用的好的介绍性文件

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

在你的第二个例子中,你通常调用该函数,并手动设置thisnew Object (或只是{} 因此,该函数运行,并设置您发送它的this对象的属性。 (尝试做人Person( "Bob", 55 );然后是console.log(window.name)

在第一个例子中, bob是一个Person对象; 但在第二天,它是一个Object

所以,不,一个人对另一个人来说并不缺乏。 他们是不同的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM