[[call]]和[[construct]]之间有什么区别?

4

在使用new调用构造函数时,不可能直接使用数组和apply(apply执行[[Call]]而不是[[Construct]])。但是,由于扩展语法,可以很容易地将数组与new一起使用。

var dateFields = [1970, 0, 1];  // 1 Jan 1970
var d = new Date(...dateFields);

为什么我们不能在构造函数中使用apply方法呢? call方法和construct方法有什么区别吗?


抱歉,您的问题核心不太清晰。请提供故事双方的代码。您所指的构造函数示例是什么意思? - user6749601
难道没有 Reflect.construct 吗? - Jonas Wilms
@JonasW,这也是ES6。同样的问题。 - Patrick Roberts
apply的作用是将参数列表作为数组传递并传递它们。请参阅**此处**。 - Rajesh
2个回答

4

构造函数通过this访问构造的对象,您可以通过apply的第一个参数轻松模拟它,因此[[Construct]]基本上只是具有不同上下文的[[Call]]:

var obj = Object.create(Date.prototype);
Date.apply(obj, dateFields);

如果您需要一个ES6版本,现在有一种新的方法可以直接调用[[construct]]:
var obj = Reflect.construct(Date, dateFields);

3

[[Call]]是通过Date(…)调用的,而[[Construct]]是通过new Date(…)调用的。如果你尝试使用new Date.apply(…, dateFields)来[[Construct]]一个Date,它实际上会在Function.prototype.apply方法上调用[[Construct]],而不是Date对象,这样并不能正确地初始化Date对象,而是尝试初始化一个[[Prototype]]等于apply.prototype的对象,因为apply()不是一个可构造的函数,所以会抛出TypeError

需要澄清的是,我并不是说在ES5中不可能将参数数组应用于Date构造函数,我只是解释为什么使用apply来[[Construct]]一个Date是行不通的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接