Существуют ли какие-либо объекты JS, для которых IsCallable имеет значение false, а IsConstructor - true? - PullRequest
0 голосов
/ 01 мая 2018

Функция спецификации ECMAScript IsCallable возвращает истину, если ее аргумент имеет внутренний метод [[Call]]. Он используется в нескольких местах в спецификации, например, в определении Array.prototype.toString.

Существует аналогичная спецификационная функция IsConstructor , которая возвращает истину, если ее аргумент имеет внутренний метод [[Construct]].

Некоторые объекты 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 {}}));

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Повторение: возможно ли для объекта X вернуть true для IsConstructor(X), но false для IsCallable(X)? Т.е. возможно ли, чтобы объект X имел внутренний метод [[Construct]], но не имел внутреннего метода [[Call]]?

Спецификация ECMAScript не настолько ясна в этом вопросе, как могла бы быть.

(1) 6.1.7.2 «Внутренние методы объекта и внутренние слоты» говорит:

A объект функции - это объект, который поддерживает внутренний метод [[Call]]. конструктор (также называемый функция конструктора ) - это функциональный объект, который поддерживает внутренний метод [[Construct]].

Из этого можно сделать вывод, что если такой объект X существует , он явно не является «функциональным объектом» и, следовательно, также не «конструктором». То есть IsConstuctor(X) вернул бы true для объекта, который не считается «конструктором», что было бы странным.

(2) Обратите внимание, что в предложении, которое определяет IsConstructor, в преамбуле говорится, что она определяет, является ли ее аргумент «функциональным объектом с внутренним методом [[Construct]]», но алгоритм не имеет явной проверки, что аргумент функциональный объект. Это говорит о том, что (по мнению автора спецификации) наличия внутреннего метода [[Construct]] достаточно, чтобы гарантировать, что аргумент является функциональным объектом, то есть у него есть внутренний метод [[Call]].

* 1 033 * (3) Единственный смысл иметь внутренний метод [[Construct]] - это вызывать его в абстрактной операции Construct . Как и в пункте (2), в преамбуле говорится, что операция «используется для вызова внутреннего метода [[Construct]] объекта функции», но алгоритм явно не проверяет, является ли F объектом функции.

Так что я полагаю, что ответ таков: хотя спецификация явно не говорит, что такие объекты не могут существовать, это довольно сильно подразумевает / предполагает, что они не существуют.


ОБНОВЛЕНИЕ (2018-05-22):

6.1.7.2 «Внутренние методы объекта и внутренние слоты» теперь изменено и теперь (выделено мной):

A объект функции - это объект, который поддерживает внутренний метод [[Call]]. Конструктор - это объект, который поддерживает внутренний метод [[Construct]]. Каждый объект, который поддерживает [[Construct]], должен поддерживать [[Call]] ; то есть каждый конструктор должен быть функциональным объектом. Следовательно, конструктор также может называться функцией конструктора или объектом функции конструктора .

0 голосов
/ 01 мая 2018

Нет, невозможно создать что-то конструктивное, но не вызываемое. Все, что определяет [[Construct]] в спецификации, является функцией, за исключением прокси, которые имеют [[Construct]] только тогда, когда их цель также делает ( 9.15.4 ).

У экзотического прокси-объекта есть внутренний метод [[Construct]], только если начальное значение его внутреннего слота [[ProxyTarget]] является объектом, у которого есть внутренний метод [[Construct]].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...