0

Функционально ли эквивалентны "(function ( ) { } ) ( )" и "(function ( ) { } ( ) )" в JavaScript?

2

Описание проблемы

У меня возник вопрос по поводу синтаксиса самовызывающейся анонимной функции в JavaScript. У меня есть два блока кода, которые, как я заметил, ведут себя идентично — они оба выводят foo, а затем bar. Единственное различие между ними заключается в синтаксисе, а именно в использовании })() и }()).

Вот оба примера кода:

Код 1:

(function()
{
    bar = 'bar';
    alert('foo');
})();

alert(bar);

Код 2:

(function()
{
    bar = 'bar';
    alert('foo');
}());

alert(bar);

В обоих случаях вывод получается одинаковым, и оба кода вызывают alert с foo, а затем выводят значение переменной bar.

Вопрос: Есть ли какие-либо различия в поведении этих двух блоков кода, кроме синтаксических? Заранее спасибо за помощь!

3 ответ(ов)

0

Нет; они идентичны.


Однако, если вы добавите new перед вызовом и .something после, они будут отличаться.

Код 1

new (function() {
    this.prop = 4;
})().prop;

Этот код создает новый экземпляр класса этой функции, затем получает свойство prop нового экземпляра.

Он возвращает 4.

Это эквивалентно следующему:

function MyClass() {
    this.prop = 4;
}
new MyClass().prop;

Код 2

new (function() {
    return { Class: function() { } }; 
}()).Class;

Этот код вызывает new на свойстве Class.

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

Выражение new парсится до .Class и создает экземпляр этого значения. (скобки после new являются необязательными)

Это эквивалентно:

var namespace = { Class: function() { } };

function getNamespace() { return namespace; }

new (getNamespace()).Class;
// Или,
new namespace.Class;

Без скобок вокруг вызова getNamespace(), это будет интерпретироваться как (new getNamespace()).Class — это создаст новый экземпляр класса getNamespace и вернет свойство Class нового экземпляра.

0

Нет никакой разницы — открывающая фигурная скобка служит только синтаксическим намеком, чтобы указать парсеру, что то, что следует за ней, является выражением функции, а не объявлением функции.

0

Нет никакой разницы. Оба варианта представляют собой функциональные выражения.

Существует и третий способ:

+function() {
    bar = 'bar';
    alert('foo');
}();

(вместо + мог бы подойти и другой оператор).

Однако самым распространённым способом является:

(function() {
    // ...
})();
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь