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

时间:2018-07-18 09:00:17

标签: javascript

使用new调用构造函数时,无法直接使用数组并应用(应用[[Call]]而不是[[Construct]])。但是,由于具有扩展语法,因此可以轻松地将数组与new一起使用。

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

那么为什么我们不能使用apply for构造函数呢? 调用和构造之间有什么区别吗?

2 个答案:

答案 0 :(得分:3)

[[Call]]通过Date(…)调用,而[[Construct]]通过new Date(…)调用。如果您试图通过Date [{Construct]] new Date.apply(…, dateFields),则它实际上是在Function.prototype.apply方法而不是Date对象上调用[[Construct]],不会正确初始化Date对象,而是尝试使用[[Prototype]]等于apply.prototype的{​​[1}}初始化对象,因为undefined不是可构造函数,因此抛出apply()

为了澄清,我并不是说不可能在ES5中将参数数组应用于TypeError构造函数,我只是在解释为什么使用Date来{ {1}}不起作用。

答案 1 :(得分:3)

构造函数使用// any receives from shutdownCh will mean the state Shutdown shutdownCh := connectionOnState(ctx, conn, connectivity.Shutdown) 访问构造的对象,可以轻松地用this的第一个参数来模拟它,因此[[Construct]]基本上只是一个[[Call]],具有不同的名称上下文:

apply

如果要使用ES6版本,可以使用一种全新的方法直接调用[[construct]]:

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