Какая разница в стиле закрытия

В javascript есть два популярных стиля закрытия. Первым вызываю анонимный конструктор:

new function() { 
  var code...
}

и встроенная выполняемая функция:

(function() {
  var code...
})();

есть ли различия в поведении между этими двумя? Одно "лучше" другого?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
22
0
1 564
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

@Lance: первый тоже выполняется. Сравните его с именованным конструктором:

function Blah() {
    alert('blah');
}
new Bla();

на самом деле это также выполняет код. То же самое и с анонимным конструктором ...

Но вопрос был не в этом ;-)

Ответ принят как подходящий

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

В основном поведение

new expression

Фактически эквивалентен

var tempObject = {};
var result = expression.call(tempObject);
if (result is not an object)
    result = tempObject;

Хотя, конечно, tempObject и result являются временными значениями, которые вы никогда не увидите (они являются деталями реализации в интерпретаторе), и нет никакого механизма JS для проверки «не является объектом».

Вообще говоря, метод new function () {..} будет работать медленнее из-за необходимости создания объекта this для конструктора.

Тем не менее, это не должно быть реальной разницей, поскольку выделение объектов не является медленным, и вы не должны использовать такой код в горячем коде (из-за стоимости создания объекта функции и связанного с ним закрытия).

Обновлено: я понял, что я упустил из этого то, что tempObject получит прототип expression, например. (до expression.call) tempObject.__proto__ = expression.prototype

Ну я сделал такую ​​страничку:

<html>
<body>
<script type = "text/javascript">
var a = new function() { 
  alert("method 1");

  return "test";
};

var b = (function() {
  alert("method 2");

  return "test";
})();

alert(a);  //a is a function
alert(b);  //b is a string containing "test"

</script>
</body>
</html>

Достаточно удивительно (по крайней мере для меня) он предупредил как «метод 1», так и метод 2 ». Я не ожидал, что будет предупрежден« метод 1 ». Разница заключалась в том, какие были значения a и b. A была сама функция, а b - это строка, возвращаемая функцией.

Да, между ними есть различия.

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

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

Пример:

<html>
<body>
<script type = "text/javascript">

new function() { 
a = "Hello";
alert(a + " Inside Function");
};

alert(a + " Outside Function");

(function() { 
var b = "World";
alert(b + " Inside Function");
})();

alert(b + " Outside Function");
</script>
</body>
</html>

В приведенном выше коде результат выглядит примерно так:

Hello Inside Function
Hello Outside Function
World Inside Function

... тогда вы получите сообщение об ошибке, поскольку 'b' не определено вне функции!

Таким образом, я считаю, что второй способ лучше ... безопаснее!

-1 Это происходит из-за того, что опущено «var» перед «a», что делает его глобальным, и не имеет отношения к вопросу.

Tomas 19.05.2010 17:43

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

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

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

Другие вопросы по теме