В чем разница между этими двумя объявлениями JavaScript?

Для одного из них "()" внутри, а для другого - снаружи. Вот они:

var a = (function() {
    return {
        bla: function() {
            console.log('a');
        }
    };
} () );

var b = (function() {
    return {
        bla: function() {
            console.log('b');
        }
    };
}) ();

a.bla();
b.bla();

Ответ 1

Нет никакой разницы.

[ненужные] круглые скобки находятся в разных местах. Объявление функции уже является выражением из-за того, где оно расположено. Скобки будут иметь значение, в то же время приводя к эквивалентному коду, если объявление было в контексте оператора (и по иронии судьбы они вернут его обратно в контекст выражения), а это не так.


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

function x () { alert("hi!") } ()

анализируется как

function x () { alert("hi!") }; ()

когда он появляется как оператор - или "элемент верхнего уровня блока" - где он анализируется как "FunctionDeclaration". Таким образом, часто используется следующая форма:

(function () { alert("hi!") })()

Это работает, потому что function ... больше не является выражением, как указано выше, а выражением (анализируется как "FunctionExpression" ), и выражение может продолжаться, поэтому Автоматическая точка с запятой не возникает, как в предыдущем случае. Также обратите внимание, что имя функции может быть опущено.

Однако, поскольку в столбце function ... появляется в справа от = (в "AssignmentExpression" ), поэтому он уже находится в контексте выражения (анализируется как "FunctionExpression" ) и, таким образом, никаких дополнительных скобок не требуется.

Все они идентичны, но я предпочитаю вторую форму (для согласованности в моем коде):

a = function () {} ()
b = (function () {}) ()
c = (function () {} ())

Счастливое кодирование.

Ответ 2

Нет никакой реальной разницы. Оба работают одинаково. Если вы хотите передать JSLint, вам нужно будет использовать первый шаблон, где круглые скобки вызова находятся внутри другого набора круглых скобок. Если вы этого не сделаете, вы получите следующую ошибку:

Переместите вызов в парны, содержащие эту функцию.

Также обратите внимание, что первый набор круглых скобок не требуется. Он будет работать без них, но снова не будет работать JSLint:

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


Несколько связанных вопросов:

Ошибка JSLint: "Переместить вызов в parens, которые содержат функцию"

Решение для ошибок JSLint

Ответ 3

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

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

Ответ 4

Я думаю, что та же разница:

var myObj = {bla:'blabla'}; 
var a = (myObj);
var b = myObj;

... нет разницы:)

Ответ 5

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

Итак, если вы используете {}(), функция немедленно выполняется и переменной присваивается результат функции.

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

Это то же самое, если они содержат те же функции, на мой взгляд.