В JavaScript, в чем преимущество!function () {} () over (function () {}) ()? [дубликат]
Возможные Дубликаты:
что означает восклицательный знак перед функцией?
Я уже давно использовал следующие для самоисполняющихся анонимных функций в JavaScript:
(function () { /* magic happens */ })()
В последнее время я начал видеть больше экземпляров следующего шаблона (например, в Bootstrap):
!function () { /* presumably the same magic happens */ }()
кто-нибудь знает, в чем преимущество второго рисунка? Или это просто стилистический предпочтения?
6 ответов:
эти два различных метода имеют функциональный разница а также разница во внешнем виде. Потенциальные преимущества одной техники перед другой будут обусловлены этими различиями.
Concision
JavaScript-это язык, где concision может быть очень важно, потому что Javascript-это загружается при загрузке страницы. Это означает, что чем более лаконичен Javascript,тем быстрее время загрузки. По этой причине, есть Javascript minifiers и обфускаторы которые сжимают файлы Javascript для оптимизации времени загрузки. Например, пробелы в
alert ( "Hi" ) ;
будет оптимизирован дляalert("Hi");
.имея это в виду, сравним эти две схемы
- нормальный закрытие:
(function(){})()
16 персонажи- отрицается закрытие:
!function(){}()
15 символовэто микро-оптимизация в лучшем случае, поэтому я не считаю это особенно убедительным аргументом, если вы не делаете гольф-кода.
отрицание возвращенного значения
сравните значение результата
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