javascript - 是否存在 IsCallable 为假但 IsConstructor 为真的 JS 对象?

标签 javascript function constructor language-lawyer

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) 返回 false )?即,对象 X 是否可能具有 [[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/

相关文章:

C++ 指向函数的指针,初学者问题

c# - 构造函数中 GetDbContext 时出现 System.ArgumentNullException

c++ - 智能指针 - 如果构造函数抛出怎么办?

javascript - 如何通过过滤嵌套属性返回父对象

javascript - 为什么这个微任务在事件循环中先于宏任务执行?

javascript - 传入一个函数,进入一个函数,稍后用参数执行?可以作为单个参数吗?

javascript - 我可以通过修改 Function 原型(prototype)在对象构造期间执行操作吗?

javascript - 如何降低 JavaScript 代码中的循环复杂度?

php - 在不更改 URL 的情况下加载页面并保持相对路径有效

vba - 类模块函数中的错误处理