(()) срещу ()() в затваряния на javascript

Знам, че това е глупаво, но има някаква разлика между това:

(function() {  
    var foo = 'bar';  
})();

и този?

(function() {  
    var foo = 'bar';  
}());

JSLint ни казва да Move the invocation into the parens that contain the function, но не виждам необходимост.

Редактиране: Отговорите са твърде готини. ~function, алтернативата JSHint заедно с предпочитанието на jQuery за (/***/)(); и обяснението на Крокфорд! Мислех, че просто ще получа отговор от типа „те са едно и също нещо“.
Вие решавате кой е най-добрият чрез гласуване „за“ и аз го отбелязвам.


person Camilo Martin    schedule 08.01.2012    source източник
comment
Тези два примера са почти еднакви, но версията dog balls връща резултата извън първия набор от скоби, докато одобрената от Crockford версия го връща вътре. Това рядко е значително, но е разлика.   -  person Okonomiyaki3000    schedule 26.01.2016
comment
@Okonomiyaki3000 Това не е разлика, освен ако не го промените значително (т.е. добавяне на още неща в скобите). Всъщност предполагам, че foo = (/***/)(); и foo = (/***/()); могат да се компилират до един и същ байт код. Помислете как (a + b) + (c + d) ще се компилира до същото като a + (b + c) + d.   -  person Camilo Martin    schedule 26.01.2016
comment
Да, foo = (/***/)(); и foo = (/***/()); са еднакви, но (foo = /***/)(); и (foo = /***/)(); не са. И да, това е педантично. Вероятно никога няма много добра причина да направите това.   -  person Okonomiyaki3000    schedule 29.01.2016
comment
@Okonomiyaki3000 Изглежда, че не е достатъчно педантично, тъй като тъкмо ще посоча, че двата примера, които казвате, че са различни, всъщност са идентични.   -  person Camilo Martin    schedule 30.01.2016
comment
Наистина. Има правописна грешка в предишния пост. Двете, които са различни, всъщност са: (foo = /***/)(); и (foo = /***/());   -  person Okonomiyaki3000    schedule 09.02.2016


Отговори (3)


Няма никаква разлика. И двата са валидни начини да накарате анализатора на JavaScript да третира вашата функция като израз вместо декларация.

Обърнете внимание, че + и ! също ще работят и понякога се използват от минификатори за запазване на символ с размер:

+function() {  
    var foo = 'bar';  
}();

!function() {  
    var foo = 'bar';  
}();

РЕДАКТИРАНЕ

Както посочва @copy, за пълнота ~ и - също ще работят.

-function() {  
    var foo = 'bar';  
}();

~function() {  
    var foo = 'bar';  
}();
person Adam Rackis    schedule 08.01.2012
comment
За пълнота ~ и - също ще направят това (всички унарни оператори). ~ е най-готиният начин разбира се. - person copy; 08.01.2012
comment
Леле, +1 за този загадъчен синтаксис! Това трябва да накара някои нищо неподозиращи програмисти да се почешат по главите, ако го видят в производство. Тогава работи ли между браузър? В спецификацията ли е? Не мога да разбера защо работи. - person Camilo Martin; 08.01.2012
comment
Леле, - и + изглеждат като Objective-C, още повече, когато дадете имена на функциите. jsfiddle.net/minitech/ugA9K - person Ry-♦; 08.01.2012
comment
@CamiloMartin - Причината за използването на () или някой от тези унарни оператори е да се принуди интерпретаторът да третира функцията като израз, а не като декларация. - person David Harkness; 08.01.2012
comment
@DavidHarkness А, разбирам. Интерпретаторът, оценяващ операнда, има смисъл сега. - person Camilo Martin; 08.01.2012
comment
@CamiloMartin - да, това е просто хак, за да накарате интерпретатора да не мисли, че това е декларация на функция -- като `function() foo {} - person Adam Rackis; 08.01.2012
comment
Намерих още някои поддържани оператори: jsfiddle.net/Gzrnu - person Camilo Martin; 08.01.2012
comment
@CamiloMartin - изглежда, че останалите оператори изискват втори операнд - x * function() {}(); Въпреки това все още е страхотно - person Adam Rackis; 08.01.2012
comment
Да, има един унарен оператор, който сте забравили! :D Но това няма да го направи по-кратко или толкова ясно. jsfiddle.net/minitech/WL8tU/1 (Също @CamiloMartin; двоичен оператор, който сте забравили .) - person Ry-♦; 08.01.2012
comment
@minitech - LOL - хареса ми този пример - това ме накара да дам +1 на твоя отговор. И да, всъщност няма причина да го използвате - със сигурност не по-кратък - person Adam Rackis; 08.01.2012
comment
Да, просто мога да си представя да видя това в The Daily WTF някой ден :) (Също така, вероятно трябва просто да +1 коментара, отговорът ми не е точно подходящ за това!) - person Ry-♦; 08.01.2012
comment
О, и още един, който е малко по-ясен, е void, въпреки че мразя тази ключова дума. (Само за пълен списък.) jsfiddle.net/WL8tU/2 - person Ry-♦; 09.01.2012
comment
Добре, въпросът е отбелязан. Ако някога видите тези аберации в производствения код на The Daily WTF някой ден, знаете какво ги е причинило ;) - person Camilo Martin; 09.01.2012
comment
@minitech Тази връзка не работи. - person QuentinUK; 23.03.2013
comment
@QuentinUK: Този jsFiddle? Сигурен ли си, че не е виновен jsFiddle? (Добавете /show.) - person Ry-♦; 23.03.2013
comment
Не съм сигурен! Но мисля, че ще се придържам към (скоби()); - person QuentinUK; 23.03.2013
comment
new function() { var foo = 'bar'; }(); Също работи ;) - person A1rPun; 27.08.2013
comment
Има разлика в логично изглеждащия синтаксис (току-що имах странен случай с приложение на трета страна), 2 бързи примера, смесени с jquery: jQuery(document).ready(function ($) { ... })(jQuery, window, document); // Bug of the plugin / wrongly written jQuery(document).ready(function ($) { … }(jQuery, window, document)); Първият се провали, ще ви даде тази грешка във вашата js конзола: TypeError : jQuery(...).ready(...) не е функция (jQuery(document).ready(function($){... Но втората минава без никакви проблеми. Не е точно същия случай като... - person ioCron; 19.06.2016
comment
разговор предполага, но може да има значение в различни сценарии, следователно трябва да се съглася с Крокфорд, просто изглежда синтактично по-правилно за мен = по-универсално / последователно за използване. - person ioCron; 19.06.2016

Това нарушение на JSLint съществува, защото Дъглас Крокфорд казва, че версията с външни скоби изглежда като "кучешки топки".

Можете да го чуете да го обсъжда в този видеоклип:

Мисля, че това изглежда глупаво, защото това, за което говорим, е цялата инвокация, но имаме тези неща, които висят отвън и изглеждат нещо като ... кучешки топки.

Той предполага, че скобите вътре помагат на читателя да разбере, че целият израз е израз на функция, а не декларация.

person Rob Hruska    schedule 08.01.2012
comment
Бих искал квадратче за отметка Ignore Douglas Crockford's preferences в JSLint. - person Camilo Martin; 08.01.2012
comment
Той оправдава много от правилата на JSLint в това видео и някои от тях имат достойни причини. Но някои от тях са и доста придирчиви. - person Rob Hruska; 08.01.2012
comment
@Rob - Знам, че се оплаква от използването на ++. Съжалявам, но никога, никога няма да се съглася с това. - person Adam Rackis; 08.01.2012
comment
@AdamRackis - Съгласен съм. И аз не мисля да спра да го използвам. - person Rob Hruska; 08.01.2012
comment
youtube.com/watch?v=dkZFtimgAcM&t=38m21s - person sym3tri; 25.12.2012
comment
Бях съгласен с @AdamRackis и @Rob, докато нашият минификатор не попадна на код на доставчик, който изглеждаше като $('el_' + ++el.id);, който го превърна в $('el_'+++el.id); - person JaredMcAteer; 01.10.2013
comment
@Jared - звучи като бъг във вашия минификатор. Коя използвате? - person Adam Rackis; 01.10.2013
comment
Това беше грешка в минификатора, но никога нямаше да е проблем, ако продавачът беше последвал препоръката на Crockford. - person JaredMcAteer; 01.10.2013
comment
имайте предвид, че това също не помага на читателя да го разбере малко или според мен точно неговите два бита. откачени разработчици... - person john Smith; 20.11.2013
comment
Странно, че в книгата си JavaScript: Добрите части, той (Крокфорд) използва стила на кучешки топки. ˁ(OᴥO)ˀ - person Glenn Mohammad; 23.03.2016
comment
@GlennMohammad коя страница? Всичко свърши? - person K-Dawg; 16.11.2018

Не, не вярвам да има разлика. Аз лично предпочитам първото (и jQuery et. al. изглежда са съгласни), но и двете работят идентично във всеки двигател, който съм тествал.

Освен това JSLint понякога е твърде строг. JSHint може да е малко по-добър в това отношение.

person Ry-♦    schedule 08.01.2012
comment
О, не знаех за JSHint. Да, само кодът, написан по време на тестване с JSLint, го преминава, никога не изглежда да мога да избегна грешки преди проверка. - person Camilo Martin; 08.01.2012