Invoking functions multiple times in a row

Refresh

November 2018

Views

72 time

3

I'm curious why:

(function () { return 'one' })()()

returns:

TypeError: (intermediate value)(...) is not a function 

and not:

TypeError: 'one' is not a function
Src

3 answers

0

Потому что , когда в фигурных скобках ()его ( function () { return 'one' }) становится выражение , которое дает промежуточные результаты , и эти результаты не связаны с переменным еще .

Согласно спецификации ,

Значения типа спецификаций являются спецификации артефактов , которые не обязательно соответствуют какой - либо конкретной организации в рамках реализации ECMAScript.

Значения типа Спецификации могут быть использованы для описания промежуточных результатов оценки экспрессии ECMAScript , но такие значения не могут быть сохранены в качестве свойств объектов или значений переменного ECMAScript языка.

2

Сообщения об ошибках использовать имена переменных или другие идентификаторы, чтобы сказать, что это не функция. Поскольку возвращаемое значение не было назначено ни к чему, он не имеет идентификатор, так говорит двигательintermediate value

2

Документация сообщения об ошибке «Ошибка типа:„х“не является функцией» объясняет:

Что пошло не так?

Он пытался вызвать значение из функции, но значение на самом деле не является функцией. Часть кода ожидает от вас, чтобы обеспечить функцию, но этого не произошло.

Она также предоставляет некоторые примеры кода, который вызывает эту ошибку и фактическое сообщение об ошибке сообщила им. Я не буду копировать их здесь, но принять, пожалуйста, поближе посмотреть на них и обратите внимание на сообщения об ошибках, они генерируют.

«Х» часть заменяется в фактических сообщений об ошибках от имени объекта , который , как ожидается , будет функция , и это не так .

Поскольку объект в данном случае не имеет имени (это промежуточный результат вычисляется при оценке выражения, см объяснение ниже), двигатель не может сообщить свое имя и старается быть полезным , как это возможно. Он сообщает «(промежуточное значение) (...)» , вероятно , потому , что таким образом он более описательный; это значение , возвращаемое функцией , которая не хранится , но используется для вычисления другого значения.

Он не может сообщить о фактической стоимости , а не потому , что промежуточное значение может быть что угодно; если это сложная структура данных , то сообщение об ошибке становится раздутым без добавления много информации.

Видимо, я не понял вопроса с первого раза, что следует мой первоначальный ответ, который объясняет, почему генерируется ошибка, а не почему сообщение об ошибке, что это такое, а не то, что ОП ожидает.


Этот код ...

(function () { return 'one' })()()
  1. ... создает анонимную функцию ...

    function () { return 'one' }
    
  2. ... называет это ...

    (function () { return 'one' })()
    
  3. ... затем пытается интерпретировать значение, возвращаемое функцией, как другую функцию и назвать его:

    (function () { return 'one' })()()
    

Функция , созданная на этапе # 1 возвращает строку ( 'one') , когда она вызывается (на шаге 2 #).

На шаге 3, эффект кода является такой же , как вызов 'one'(). Это не то же самое one()(как вы могли бы подумать).

Промежуточное значение, указанное в сообщении об ошибке является строкой, возвращаемой при первом вызове функции, которая затем используется в выражении (как функция) без сохранения в переменном (это объяснение «промежуточной» формулировки.)

По мере того как сообщение об ошибке ясно говорит, 'one'не является функцией и пытается использовать его в качестве функции (путем размещения второй пары скобок в выражении) не работает.

Для того, чтобы заставить его работать, анонимная функция, созданная на шаге 1 должен возвратить другой (анонимный) функцию, как это:

(function() { return function() { return 'one'; } })()()

Теперь, когда она вызывается внешняя функция возвращает анонимную функцию, которая схожа с анонимной функции , созданной на шаге 1 исходным кодом. Когда эта функция вызывается (второй ()) возвращает строку 'one'.

Это, вероятно , не то , что вы хотели. Вызов функции , заданной ее имя в виде строки можно только с помощью eval()которой является язык функция, лучше избегать (несколько сильных причин.)