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 {}}));
最佳答案
重述:对象 X 是否有可能为 IsConstructor(X)
返回 true
但为 IsCallable(X) 返回
?即,对象 X 是否可能具有 false
)[[Construct]]
内部方法但没有 [[Call]]
内部方法?
ECMAScript 规范在这一点上并没有像它应该的那样明确。
(1) 6.1.7.2 "Object Internal Methods and Internal Slots"说:
A function object is an object that supports the [[Call]] internal method. A constructor (also referred to as a constructor function) is a function object that supports the [[Construct]] internal method.
由此我们可以得出结论,如果这样的对象 X 确实 存在,那么它显然不是“函数对象”,因此也不是“构造函数”。 IE。 IsConstuctor(X)
将为不被视为“构造函数”的对象返回 true
,这很奇怪。
(2)
请注意,在定义 IsConstructor
的子句中,序言说明它确定其参数是否“是具有 [[Construct]] 内部方法的函数对象”,但该算法没有明确的检查参数是否为函数对象。这表明(规范编写者认为)具有 [[Construct]] 内部方法足以保证参数是一个函数对象,即它具有 [[Call]] 内部方法。
(3)
拥有 [[Construct]]
内部方法的唯一要点是在 the Construct
abstract operation 中调用它.与第 (2) 点类似,序言中说该操作“用于调用函数对象的 [[Construct]] 内部方法”,但该算法并未明确检查 F
是一个函数对象。
所以我相信答案是,虽然规范没有明确说这样的对象不存在,但它相当强烈地暗示/假设它们不存在。
更新(2018-05-22):
6.1.7.2 "Object Internal Methods and Internal Slots"现在已修改为(强调我的):
A function object is an object that supports the [[Call]] internal method. A constructor is an object that supports the [[Construct]] internal method. Every object that supports [[Construct]] must support [[Call]]; that is, every constructor must be a function object. Therefore, a constructor may also be referred to as a constructor function or constructor function object.
关于javascript - 是否存在 IsCallable 为假但 IsConstructor 为真的 JS 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50109554/