В 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