Javascript: синтаксис и новое ключевое слово - PullRequest
2 голосов
/ 07 января 2020

Рассмотрим класс, определенный как:

class Foo { static bar() { return this; } }

Я могу создать экземпляр с new (Foo.bar())().

Но new Foo.bar()() приведет к Uncaught TypeError: Foo.bar is not a constructor.

Зачем нужны эти дополнительные скобки?

Ответы [ 2 ]

2 голосов
/ 09 января 2020

new Foo.bar()() идентичен (new Foo.bar())().

Просмотр страницы MDN для определения приоритета оператора , new и вызов функции находятся в одной группе. В спецификации c обработка new может несколько запутать. Однако сначала будет выполнено new.

Хороший инструмент для проверки того, как анализируется указанный фрагмент c, - https://astexplorer.net/ - он позволяет взглянуть на AST , который является результатом синтаксического анализа.

В этом случае вы получаете сообщение об ошибке от Foo.bar, являющегося методом класса, который не имеет [[Construct]] и не может использовать с new.

Подсказка: когда немного неясно, как будет анализироваться выражение, добавление явных фигурных скобок часто улучшает читабельность, даже если в них нет необходимости.

0 голосов
/ 07 января 2020
  • Во-первых, вам нужно знать, что такое IIFE (немедленно вызывается выражение функции). Как следует из названия, IIFE вы можете вызывать функцию сразу после объявления. Но JS парсер должен видеть целое как одно выражение.

Пример.

(function(){console.log("foo")}())

!function(){console.log("foo")}()

+function(){console.log("foo")}()

Все это заставляет синтаксический анализатор видеть сторону function(){console.log("foo")}() как полное выражение, чтобы он мог немедленно вызвать.

  • Во-вторых, как работает new (Foo.bar())().

При использовании new (Foo.bar())() в первых скобках возвращается this, что само по себе Foo. Потому что bar метод возвращает Foo. После вторых скобок () вызывает его (Foo), а затем new создает новый экземпляр Foo. В основном вы пишете new Foo() с использованием IIEF.

  • В-третьих, почему new Foo.bar()() выдает ошибку.

Когда JS синтаксический анализатор видит выражение new Foo.bar(), это немедленно попробуйте создать экземпляр, если Foo.bar и Foo.bar не является конструктором. После этого JS выдает эту ошибку.

Но если парсер видит (), он может выдать еще одну ошибку, Uncaught SyntaxError: Unexpected token ')'. Поскольку JS не может понять, что осталось от этой строки, ().

Разница между

new Foo.bar()() и new (Foo.bar())()

такая же, как

function(){console.log("foo")}() и (function(){console.log("foo")})()

он вызывает другую ошибку и прекращает синтаксический анализ, потому что Foo.bar не является конструктором для вызова.

Надеюсь, это поможет.

Некоторые ссылки для понимания. Что делает восклицательный знак перед функцией?

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