Функционально ли эквивалентны "(function ( ) { } ) ( )" и "(function ( ) { } ( ) )" в JavaScript?
Описание проблемы
У меня возник вопрос по поводу синтаксиса самовызывающейся анонимной функции в JavaScript. У меня есть два блока кода, которые, как я заметил, ведут себя идентично — они оба выводят foo
, а затем bar
. Единственное различие между ними заключается в синтаксисе, а именно в использовании })()
и }())
.
Вот оба примера кода:
Код 1:
(function()
{
bar = 'bar';
alert('foo');
})();
alert(bar);
Код 2:
(function()
{
bar = 'bar';
alert('foo');
}());
alert(bar);
В обоих случаях вывод получается одинаковым, и оба кода вызывают alert
с foo
, а затем выводят значение переменной bar
.
Вопрос: Есть ли какие-либо различия в поведении этих двух блоков кода, кроме синтаксических? Заранее спасибо за помощь!
3 ответ(ов)
Нет; они идентичны.
Однако, если вы добавите 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
нового экземпляра.
Нет никакой разницы — открывающая фигурная скобка служит только синтаксическим намеком, чтобы указать парсеру, что то, что следует за ней, является выражением функции, а не объявлением функции.
Нет никакой разницы. Оба варианта представляют собой функциональные выражения.
Существует и третий способ:
+function() {
bar = 'bar';
alert('foo');
}();
(вместо +
мог бы подойти и другой оператор).
Однако самым распространённым способом является:
(function() {
// ...
})();
Установка значения по умолчанию для параметра функции в JavaScript
В чем разница между call и apply?
Проверка существования переменной в JavaScript (определена/инициализирована)
Определение глобальной переменной в функции JavaScript
Как лучше реализовать необязательные параметры функций в JavaScript?