Функция JavaScript, ведущая взрыва! синтаксис
Я видел этот синтаксис в нескольких библиотеках сейчас, и мне интересно, какова выгода. (заметьте, я хорошо осведомлен о замыканиях и о том, что делает код, меня интересуют только синтаксические различия)
!function(){
// do stuff
}();
Как альтернатива более распространенным
(function(){
// do stuff
})();
для самостоятельного вызова анонимных функций.
Мне интересно несколько вещей. Прежде всего, что позволяет верхнему примеру на самом деле работать? Почему взрыв необходим для того, чтобы сделать это утверждение синтаксически правильным? Мне также сказали, что +
работает, и я уверен, что некоторые другие, вместо !
Во-вторых, в чем выгода? Все, что я могу сказать, это то, что он сохраняет одного персонажа, но я не могу себе представить, что это такое огромное преимущество для привлечения многочисленных усыновителей. Есть ли какая-то другая выгода, которую я пропускаю?
Единственное другое отличие, которое я вижу, это возвращаемое значение функции, вызывающей саму себя, но в обоих этих примерах нас не волнует возвращаемое значение функции, поскольку она используется только для создания замыкания. Так может кто-нибудь сказать мне, почему можно использовать первый синтаксис?
7 ответов
В идеале вы должны быть в состоянии сделать все это просто так:
function(){
// do stuff
}();
Это означает объявить анонимную функцию и выполнить ее. Но это не сработает из-за особенностей грамматики JS.
Таким образом, кратчайшая форма достижения этого заключается в использовании некоторого выражения, например UnaryExpression (и так CallExpression):
!function(){
// do stuff
}();
Или для удовольствия:
-function(){
// do stuff
}();
Или же:
+function(){
// do stuff
}();
Или даже:
~function(){
// do stuff
return 0;
}( );
В Javascript строка начинается с function
как ожидается, будет оператором функции и должен выглядеть
function doSomething() {
}
Самопризывающаяся функция, как
function(){
// do stuff
}();
не соответствует этой форме (и вызовет синтаксическую ошибку в первом открытии, потому что нет имени функции), поэтому скобки используются для определения выражения анонимной функции.
(function(){
// do stuff
})();
Но все, что создает выражение (в отличие от оператора функции), будет делать, поэтому !
, Он говорит интерпретатору, что это не оператор функции. Помимо этого, приоритет оператора определяет, что функция вызывается до отрицания.
Я не знал об этом соглашении, но если оно станет распространенным, оно может способствовать удобочитаемости. Я имею в виду, что кто-нибудь читает !function
наверху большого блока кода будет ожидаться самовывоз, как мы уже привыкли ожидать того же самого, когда увидим (function
, За исключением того, что мы потеряем эти раздражающие скобки. Я ожидаю, что это причина, в отличие от какой-либо экономии скорости или количества символов.
Помимо того, что уже было сказано, синтаксис с! полезно, если вы пишете JavaScript без точек с запятой:
var i = 1
!function(){
console.log('ham')
}()
i = 2
(function(){
console.log('cheese')
})()
Первый пример выдает 'ham', как и ожидалось, но второй выдает ошибку, потому что оператор i = 2 не завершается из-за следующей круглой скобки.
Также в сцепленных файлах javascript вам не нужно беспокоиться, если в предыдущем коде отсутствуют точки с запятой. Так что нет необходимости в общем;(function(){})(); чтобы убедиться, что ваш собственный не сломается.
Я знаю, что мой ответ немного поздний, но я думаю, что он еще не был упомянут:)
С одной стороны, jsPerf показывает, что с помощью !
(UnaryExpression's) обычно быстрее. Иногда они оказываются равными, но когда это не так, я еще не видел, чтобы один не одержал победу над другими: http://jsperf.com/bang-function
Это было протестировано на последней версии Ubuntu с самой старой (скажем..) версией Chrome 8. Поэтому результаты могут отличаться, конечно.
Редактировать: Как насчет чего-то сумасшедшего, как delete
?
delete function() {
alert("Hi!");
}();
или же void
?
void function() {
alert("Hi!");
}();
Как вы можете видеть здесь, лучший способ сделать самозванный метод в javascript - это использовать:
(function(){}()); -> 76,827,475 ops/sec
!function(){}(); -> 69,699,155 ops/sec
(function(){})(); -> 69,564,370 ops/sec
Итак, с отрицанием "!" и все другие унарные операторы, такие как +,-,~, delete, void, много сказано, просто для подведения итогов:
!function(){
alert("Hi!");
}();
Или же
void function(){
alert("Hi!");
}();
Или же
delete function(){
alert("Hi!");
}();
И еще несколько случаев с бинарными операторами для удовольствия:)
1 > function() {
alert("Hi!");
}();
Или же
1 * function() {
alert("Hi!");
}();
Или же
1 >>> function() {
alert("Hi!");
}();
Или даже
1 == function() {
alert("Hi!");
}();
Оставив троицу для кого-то еще, ребята:)
Это хорошая задача для использованияvoid
оператор из-за принудительного вычисления выражения.