是否存在IsCallable为false但IsConstructor为true的JS对象? [英] Are there any JS objects for which IsCallable is false but IsConstructor is true?

查看:62
本文介绍了是否存在IsCallable为false但IsConstructor为true的JS对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ECMAScript规范函数 IsCallable 如果其参数具有[[Call]]内部方法,则返回true.它在规范中的多个地方使用,例如在

The ECMAScript specification function IsCallable returns true iff its argument has a [[Call]] internal method. It is used in several places in the specification, such as in the definition of Array.prototype.toString.

有一个类似的规范函数 IsConstructor 如果其参数具有[[Construct]]内部方法,则返回true.

There is a similar specification function IsConstructor which returns true iff its argument has a [[Construct]] internal method.

某些JS对象(包括大多数内置函数,例如 escape )是可调用的,但不可构造.是否有任何可构造但不可调用的东西?

Some JS objects, including most built-in functions such as escape are callable but not constructible. Are there any which are constructible but not callable?

请注意,用户定义类和内置类在作为普通函数调用时都会抛出 TypeError ,但根据IsCallable的定义仍然可以调用,这可以通过查看 Array是否可以确定.prototype.toString 将尝试使用它们作为 join 的实现:

Note that both user-defined and built-in classes throw TypeError when called as ordinary functions, but are still callable per the definition of IsCallable, as can be determined by seeing if Array.prototype.toString will attempt to use them as the implementation of 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)的code> false ?即,对象X是否可以具有 [[Construct]] 内部方法,而没有 [[Call]] 内部方法?

Restatement: Is it possible for an object X to return true for IsConstructor(X) but false for IsCallable(X)? I.e., is it possible for an object X to have a [[Construct]] internal method but not have a [[Call]] internal method?

在这一点上,ECMAScript规范不够清晰.

The ECMAScript spec isn't as clear-cut on this point as it could be.

(1) 6.1.7.2对象内部方法和内部插槽"说:

功能对象是支持[[Call]]内部方法的对象.构造函数(也称为构造函数)是支持[[Construct]]内部方法的函数对象.

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 ,这很奇怪.

From this we can conclude that if such an object X does exist, it is clearly not a 'function object' and thus also not a 'constructor'. I.e. IsConstuctor(X) would return true for an object that isn't deemed a 'constructor', which would be odd.

(2)请注意,在定义 IsConstructor 的子句中,序言说它确定其参数是否是具有[[Construct]]内部方法的函数对象",但是该算法没有显式的检查参数是否为函数对象.这表明(规范编写者认为)具有[[Construct]]内部方法就足以保证该参数是一个函数对象,即它具有[[Call]]内部方法.

(2) Note that in the clause that defines IsConstructor, the preamble says that it determines whether its argument "is a function object with a [[Construct]] internal method", but the algorithm doesn't have an explicit check that the argument is a function object. This suggests that (the spec-writer thought that) having a [[Construct]] internal method is sufficient to guarantee that the argument is a function object, i.e. that it has a [[Call]] internal method.

(3)拥有 [[Construct]] 内部方法的唯一点是在 F 是否为一个功能对象.

(3) The only point to having a [[Construct]] internal method is to invoke it in the Construct abstract operation. Similar to point (2), the preamble says that the operation "is used to call the [[Construct]] internal method of a function object", but the algorithm doesn't explicitly check that F is a function object.

因此,我相信答案是,尽管规范没有明确地表示此类对象不存在,但它强烈暗示/假定它们不存在.

So I believe the answer is that, while the spec doesn't explicitly say that such objects can't exist, it fairly strongly implies/assumes that they don't.

更新(2018-05-22):

UPDATE (2018-05-22):

6.1.7.2对象内部方法和内部广告位" 现在已修改为(强调我的意思):

6.1.7.2 "Object Internal Methods and Internal Slots" has now been modified to say (emphasis mine):

功能对象是支持[[Call]]内部方法的对象.构造函数是一个支持[[Construct]]内部方法的对象.每个支持[[Construct]]的对象都必须支持[[Call]] ;也就是说,每个构造函数都必须是一个函数对象.因此,构造函数也可以称为构造函数构造函数对象.

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.

这篇关于是否存在IsCallable为false但IsConstructor为true的JS对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆