В JavaScript, в чем преимущество!function () {} () over (function () {}) ()? [дубликат]


Возможные Дубликаты:
что означает восклицательный знак перед функцией?

Я уже давно использовал следующие для самоисполняющихся анонимных функций в JavaScript:

(function () { /* magic happens */ })()

В последнее время я начал видеть больше экземпляров следующего шаблона (например, в Bootstrap):

!function () { /* presumably the same magic happens */ }()

кто-нибудь знает, в чем преимущество второго рисунка? Или это просто стилистический предпочтения?

6 77

6 ответов:

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

Concision

JavaScript-это язык, где concision может быть очень важно, потому что Javascript-это загружается при загрузке страницы. Это означает, что чем более лаконичен Javascript,тем быстрее время загрузки. По этой причине, есть Javascript minifiers и обфускаторы которые сжимают файлы Javascript для оптимизации времени загрузки. Например, пробелы в alert ( "Hi" ) ; будет оптимизирован для alert("Hi");.

имея это в виду, сравним эти две схемы

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

отрицание возвращенного значения

сравните значение результата a и b.

var a = (function(){})()
var b = !function(){}()

С

Я всегда возвращаюсь на часть жизни Бена Альмана для таких вопросов, как этот. Это окончательно, насколько я могу судить.

вот мясо статьи:

// Either of the following two patterns can be used to immediately invoke
// a function expression, utilizing the function's execution context to
// create "privacy."

(function(){ /* code */ }()); // Crockford recommends this one
(function(){ /* code */ })(); // But this one works just as well

// Because the point of the parens or coercing operators is to disambiguate
// between function expressions and function declarations, they can be
// omitted when the parser already expects an expression (but please see the
// "important note" below).

var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();

// If you don't care about the return value, or the possibility of making
// your code slightly harder to read, you can save a byte by just prefixing
// the function with a unary operator.

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

// Here's another variation, from @kuvos - I'm not sure of the performance
// implications, if any, of using the `new` keyword, but it works.
// http://twitter.com/kuvos/status/18209252090847232

new function(){ /* code */ }
new function(){ /* code */ }() // Only need parens if passing arguments

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

использовать скобки для группировки выражений или с помощью ! отрицание возврата-это просто методы изменения синтаксического анализа. Затем он немедленно вызывается следующими родителями. Все эти формы имеют тот же эффект в этом отношении, при условии отсутствия явное возвращаемое значение:

(function(){ /* ... */ })(); // Arguably most common form, => undefined
(function(){ /* ... */ }()); // Crockford-approved version, => undefined
!function(){ /* ... */ }();  // Negates the return, so => true
+function(){ /* ... */ }();  // Attempts numeric conversion of undefined, => NaN
~function(){ /* ... */ }();  // Bitwise NOT, => -1

Если вы не фиксируете возвращаемое значение, нет никакой существенной разницы. Можно утверждать, что ~ может быть быстрее op, так как это просто переворачивание бит, или, может быть ! это более быстрый op, так как это истинная/ложная проверка и возврат отрицания.

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

У Бена Альмана есть фантастическая запись на эту тему:http://benalman.com/news/2010/11/immediately-invoked-function-expression/

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

ты об этом спрашиваешь? Они делают не сделать то же самое.

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

кроме того, это на один символ меньше.

Ну в первом случае вы используете ( ) чтобы обернуть объект, который вы хотите выполнить со следующим набором (), и в следующем случае, если вы используете оператор, который принимает один аргумент (оператор отрицания !) и вы делаете это неявно обернуть свой аргумент (funcion) с ( ) Так что вы на самом деле получите !(function () { })(), выполните функцию и отмените результат, который она возвращает. Это также может работать с -, +, ~ в том же принципе, так как все эти операторы принимают один аргумент.

!function () { /* presumably the same magic happens */ }()
-function () { /* presumably the same magic happens */ }()
+function () { /* presumably the same magic happens */ }()
~function () { /* presumably the same magic happens */ }()

зачем вы хотите это сделать? Я думаю, что это личное предпочтение или если у вас есть большой .JS и хотите сохранить 1 символ на анонимный вызов функции... : D