如果ECMAScript规范函数IsCallable的参数具有[[Call]]内部方法,则返回true。它在规范中的几个地方使用,例如Array.prototype.toString
的定义。
有一个类似的规范函数IsConstructor,如果它的参数有一个[[Construct]]内部方法,则返回true。
一些JS对象,包括大多数内置函数,如escape
,都是可调用的,但不可构造。 是否有可构造但不可赎回的内容?
请注意,用户定义的类和内置类在作为普通函数调用时抛出TypeError
,但仍可根据IsCallable的定义调用,可以通过查看Array.prototype.toString
是否会尝试来确定将它们用作join
:
// {} is not callable, so toString falls back to Object.prototype.toString:
console.log('null:', Array.prototype.toString.apply({join: {}}));
// WeakMap is callable (but throws TypeError):
console.log('null:', Array.prototype.toString.apply({join: WeakMap}));
// User-defined classes also callable:
console.log('null:', Array.prototype.toString.apply({join: class Foo {}}));
答案 0 :(得分:3)
重述:对象X是否可以为true
返回IsConstructor(X)
,而为false
返回IsCallable(X)
?即,对象X是否可以使用[[Construct]]
内部方法但是没有[[Call]]
内部方法?
ECMAScript规范并不像这一点那样明确。
(1) 6.1.7.2 "Object Internal Methods and Internal Slots"说:
函数对象是一个支持[[Call]]内部方法的对象。 构造函数(也称为构造函数)是一个支持[[Construct]]内部方法的函数对象。
由此我们可以得出结论,如果存在这样的对象X ,那么它显然不是一个'功能对象'因此也不是“构造函数”。即对于不被视为“构造函数”的对象,IsConstuctor(X)
会返回true
,这将是奇怪的。
(2)
请注意,在定义IsConstructor
的子句中,前导码表示它确定其参数"是否是具有[[Construct]]内部方法"的函数对象,但算法不是t明确检查参数是否为函数对象。这表明(规范作者认为)具有[[Construct]]内部方法足以保证参数是一个函数对象,即它具有[[Call]]内部方法。
(3)
拥有[[Construct]]
内部方法的唯一要点是在the Construct
abstract operation中调用它。与点(2)类似,前导码表示操作"用于调用函数对象的[[Construct]]内部方法",但算法没有明确检查{{ 1}}是一个函数对象。
所以我相信答案是,虽然规范并没有明确说这些对象不存在,但它强烈暗示/假设他们不会这样做。吨。
更新(2018-05-22):
6.1.7.2 "Object Internal Methods and Internal Slots"现在已被修改为(强调我的):
函数对象是一个支持[[Call]]内部方法的对象。 构造函数是一个支持[[Construct]]内部方法的对象。 支持[[Construct]]的每个对象都必须支持[[Call]] ;也就是说,每个构造函数都必须是一个函数对象。因此,构造函数也可以称为构造函数或构造函数对象。
答案 1 :(得分:2)
不,不可能创建可构造但不可调用的东西。在规范中定义[[Construct]]的所有东西都是除了代理之外的函数,代理只有[[Construct]],而它们的目标也是(9.15.4)。
如果[[ProxyTarget]]内部插槽的初始值是具有[[Construct]]内部方法的对象,则代理异类对象只有[[Construct]]内部方法。