функция JavaScript, ведущая взрыва! синтаксис - PullRequest
198 голосов
/ 29 апреля 2011

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

!function(){
  // do stuff
}();

Как альтернатива более распространенному

(function(){
  // do stuff
})();

для самостоятельного вызова анонимных функций.

Мне интересно несколько вещей. Прежде всего, что позволяет верхнему примеру на самом деле работать? Почему взрыв необходим для того, чтобы сделать это утверждение синтаксически правильным? Мне также сказали, что + работает, и я уверен, что некоторые другие, вместо !

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

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

Ответы [ 6 ]

93 голосов
/ 29 апреля 2011

В идеале вы должны быть в состоянии сделать все это просто как:

function(){
  // do stuff
}(); 

Это означает объявить анонимную функцию и выполнить ее.Но это не сработает из-за особенностей грамматики JS.

Поэтому самая короткая форма достижения этой цели - использовать некоторое выражение, например UnaryExpression (и так CallExpression):

!function(){
  // do stuff
}(); 

Или для удовольствия:

-function(){
  // do stuff
}(); 

Или:

+function(){
  // do stuff
}(); 

Или даже:

~function(){
  // do stuff
  return 0;
}( );
72 голосов
/ 29 апреля 2011

В Javascript строка, начинающаяся с function, должна быть функцией оператор и должна выглядеть как

function doSomething() {
}

Самовозвратная функция, такая как

function(){
  // do stuff
}();

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

(function(){
  // do stuff
})();

Но все, что создает выражение (в отличие от оператора функции), подойдет, поэтому отсюда и !. Он говорит интерпретатору, что это не оператор функции. Помимо этого, приоритет оператора диктует, что функция вызывается до отрицания.

Я не знал об этом соглашении, но если оно станет распространенным, оно может способствовать удобочитаемости. Я имею в виду, что любой, читающий !function в верхней части большого блока кода, будет ожидать самовозбуждения, как мы уже привыкли ожидать того же, когда увидим (function. За исключением того, что мы потеряем эти раздражающие скобки. Я ожидаю, что в этом причина, в отличие от любой экономии в скорости или количестве символов.

44 голосов
/ 17 января 2012

Помимо того, что уже было сказано, синтаксис с!полезно, если вы пишете javascript без точек с запятой:

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()

В первом примере выдается 'ham', как и ожидалось, но во втором будет выдана ошибка, поскольку оператор i = 2 не завершается из-за следующих скобок,

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

Я знаю, что мой ответ немного запоздал, но я думаю, что он еще не был упомянут:)

6 голосов
/ 29 апреля 2011

Во-первых, jsPerf показывает, что использование ! (UnaryExpression's) обычно быстрее.Иногда они оказываются равными, но когда это не так, я еще не видел безудержного одного триумфа над другими: http://jsperf.com/bang-function

Это былопротестировано на последней версии Ubuntu с самой старой (скажем ..) Chrome версии 8. Так что результаты могут отличаться, конечно.1012 * или void?

void function() {
   alert("Hi!"); 
}();
3 голосов
/ 20 января 2016

Как вы можете видеть здесь , лучший способ сделать самовыводимые методы в javascript - это:

(function(){}()); -> 76,827,475 ops/sec

!function(){}();  -> 69,699,155 ops/sec

(function(){})(); -> 69,564,370 ops/sec
3 голосов
/ 14 мая 2013

Итак, с отрицанием "!" и все другие унарные операторы, такие как +, -, ~, 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!"); 
}();

Оставив троицу для кого-то еще, ребята:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...