JavaScript'te parantez içeren bir işlevi çağırmam bir fark yaratır mı?


105

Boş parantezli veya parantezsiz bir işlevi çağırırken bir fark gördüm. Bununla birlikte, işleve herhangi bir argüman iletmiyorum, bu yüzden merak ettim, aşağıdakiler arasındaki fark ne olurdu:

window.onload = initAll();

ve

window.onload = initAll;

Lütfen arkasındaki prensibi açıklayın.


24
@JS Bangs - Yalnızca ABD İngilizcesi; başka yerde değil. Programcılar karışıklığı önlemek için bunlara "parantez" demeye eğilimli olsalar da, İngiltere İngilizcesinde yuvarlatılmış olanlar parantez olarak bilinir. Köşeli olanlar "köşeli parantez" olarak bilinir. en.wikipedia.org/wiki/Bracket
Rob Levine

13
ciddi bir kayda göre, resmi UNICODE adı Parenthesis'tir. 0028 ( sol parantez = açılış parantez (1.0) ve 0029 ) sağ parantez = kapanış parantez (1.0) - unicode.org/charts/charindex.html#P ve hangi Dictionary.com bu konuda söylenecek var - dictionary.reference.com/ browse / PARENTHESIS "Dik eğri çizgilerden biri veya her ikisi, () ..."

8
Yani bu sadece "ABD İngilizcesi" bir şey değil, Uluslararası bir standart tanımdır çünkü UNICODE Uluslararası bir Standarttır.

2
@fuzzy - Gerçeklerinizi cidden nereden alıyorsunuz? {}buna sincap parantez denir.
Anurag

7
@fuzzy lolipop - Unicode, karakterleri isimlendirmede değil bayt olarak kodlamada uluslararası bir standarttır. Unicode belgesinin yazarları, bir karakter için verilen adın uluslararası bir standart olduğunu iddia etmiyorlar. Tanımladıkları karaktere karşı koddur. Ancak, [ve] 'yi köşeli parantez olarak da ifade ettiklerini (yalnızca "köşeli parantezler" olarak değil) ve [, {ve (köşeli parantez karakterleri olarak) ifadelerinin tümünü belirtmek isteyebilirsiniz. Nüansları anlamaya çalışmalısınız farklı yerlerde aynı kelimeleri kullanma şekli. Uluslararası bir takımın parçasıysanız çok önemli.
Rob Levine

Yanıtlar:


161
window.onload = initAll();

Bu, hemen çalıştırılır ve fonksiyonun dönüş değerini a atar . Bu genellikle istediğiniz şey değildir . bunun mantıklı olması için bir işlev döndürmesi gerekir.initAll() window.onloadinitAll()

window.onload = initAll;

Bu atar gerçek işlevi için window.onloadbunu yürütme olmadan - - JavaScript, @Felix söylediği gibi, fonksiyonlar birinci sınıf nesnelerdir çünkü bu mümkündür. initAllload olayı tarafından yürütülecektir.


18
Burada belirtilmesi gereken önemli, işlevlerin JavaScript'teki birinci sınıf nesneler olmasıdır.
Felix Kling

136

Pekka'nın söylediği doğru, ancak işlev işaretlerini veya delegeleri tam olarak anlamayan birine açıklamaya yardımcı olacak bir örnekle biraz ayrıntıya girmek istiyorum.

Ben kullanmaz window.onloadgöstermek için yapmacık biraz çünkü. Bunun yerine demo yapmak için basit bir çarpma işlevi kullanacağım:

function Multiply(operator, operand) {
    return operator * operand;
}

Bu eşit şekilde yazılabilir:

Multiply = function(operator, operand) {
    return operator * operand;
}

İlk örnekte, çıkarım açık olmasa da, ikinci örnek, adı verilen bir değişkene 2 parametresi olan bir işlevi atadığımızı daha açık bir şekilde göstermektedir Multiplyve bu işlev kavramı, atama olarak JavaScript'te yaygındır. Bu, işlevlerin "birinci sınıf vatandaşlar" olduklarının, yani değerlerin etrafından dolaşıyormuşuz gibi dolaştıkları gerçeğinin küçük bir göstergesidir .

Öyleyse şimdi görev farkına gelelim:

var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);

Ret değişkenini tanımlama noktasında Multiplyçalıştırılır ve dönüş değeri atanır - ret12'ye eşit olur.

Bunu tekrar farklı bir şekilde deneyelim:

var operator = 3;
var operand = 4;
var ret = Multiply;

Şimdi, tanımlama noktasında ret, retsenin olur Multiplysenin elde edilen sonuç olmanın aksine fonksiyonu Multiplyişlevi. Çağrılar ret(), Multiplyişlevinizin yürütülmesine neden olur ve tam olarak aradığınız gibi çağırabilirsiniz Multiply(operator, operand):

var out = ret(3, 4);

aynıdır

var out = Multiply(3, 4);

retTemsilci olarak kullanacağınızı etkili bir şekilde söylediniz Multiply(). Ararken retgerçekten Multiplyişleve atıfta bulunuyoruz .

Geri dön window.onload. Bunu şu şekilde düşünün:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

initAll = function() {
    return 12;
}

Gördüğünüz window.onloadgibi, diğer herhangi bir işlev gibi bir işlev, özel bir yanı yok. Ona bir değer atayabilir, ona bir işlev atayabilir, isterseniz geçersiz kılabilirsiniz - mesele şu ki window.onload, kendi işlevinizle ilgili olduğundan daha özel bir şey yoktur . Sadece biraz farklı olan şey, yüklendiğinde pencereden çağrılmasıdır. [Feragatname: Aslında pencere işlevlerini hiçbir zaman geçersiz kılmadım, bu yüzden bunun olumsuz tepkilere neden olup olmayacağından emin değilim. Biri, ie if (window.onload) window.onload();] çağrılmadan önce bir işlevin atanıp atanmadığını kontrol etmelerini umabilir .

Şimdi initAll()söylediğimiz şudur:

window.onload = initAll();

diyebilir ki:

window.onload = 12;

Dediğimiz Ama initAllparantez olmadan ne biz gerçekten söylüyorsun: Ben benim window.onload fonksiyonu yeni işlevle, her ne değiştirmek istiyor - yani benim ile değiştirmek istediğiniz initAllişlevi böylece herhangi aramalar window.onloadçalışır benim initAllkodu.

Yani:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

şununla değiştirilir:

window.onload = function() {
    return 12;
}

Bu nedenle, herhangi bir çağrı , başlangıçta olan şey yerine işlevinizi window.onloadyürütecektir . Orijinal işlevi yeni işlevinizle değiştirdiniz.initAllwindow.onload

Aslında, olabilir eşit yazın:

window.onload = function() {
    //Write all your init code right in here instead of having a separate 
    //initAll function.
}

Daha iyi gösterebilecek bir başka örnek şudur:

var d = new Date();
var currentTime = d.getTime();

Zamanın dtanımlandığı zaman ne olursa olsun atanır currentTime. Harika, ancak bu yalnızca bu kodu içeren işlevin ne zaman çağrıldığını - yani sayfa yükleme zamanında - öğrenmek istiyorsak yararlıdır. Ya currentTimearanan herhangi bir zamanda şimdiki zamanı istersek ?

var currentTime = function() {
    var d = new Date();
    return d.getTime();
}

var a = currentTime(); //The current time at the point a is defined...
var b = currentTime;   //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined

Dediğimiz nasıl Bildirimi b()bizim içinde cve dArayabileceğimiz tam olarak atamaları currentTime()?


Harika cevap!
Shadi Almosri

Hey, ya bir olay dinleyicisine argümanlar alan bir işlev eklemek istersem?
Shemiroth

16

JavaScript'teki işlevler birinci sınıf vatandaşlardır ve bu nedenle diğer değişkenlere atanabilir veya bağımsız değişken olarak aktarılabilir.

Yani ne zaman yaparsan

window.onload = initAll;

Nesnenin onloadözelliğini window, initAllişlevin kendisine başvuracak şekilde ayarlıyorsunuz .

Ne zaman yaparsan

window.onload = initAll();

Sen ayarlarken onloadtutmak için özellik dönüş değeri o hat üzerinde yer çalıştırır beri initAll ait.


10

initAll bir işlev değerine bir referanstır ve işlev adına eklenen parantez operatörü bu işlev nesnesini ÇALIŞTIRIR.

Yani böyle bir şey yaparsan

a = initAll

daha sonra aaynı hale gelir initAll- örneğin yapabilirsiniz a()- ancak

a = initAll()

değişken a, çalıştırılan initAllişlevin dönüş değerini alır


8

6 yıl geciktim ama bunun yukarıdaki cevaplardan çok daha basit bir şekilde açıklanabileceğini düşünüyorum.

İşte TLDR ; veya 's kullanarak ve kullanmadan işlevleri çağırırken kuş bakışı görünüm()

Bu işlevi örneğin ele alalım:

function foo(){
return 123;
}

"foo" günlüğe kaydederseniz - olmadan ()

console.log(foo); 

---outout------
function foo(){
return 123;
}

Hiçbir kullanma ()aracı için işlevini kendisi getir . Geri arama olarak iletilmesini istiyorsanız bunu yaparsınız.


"foo ()" günlüğe kaydederseniz - ile ()

console.log(foo());
-----output-----
 123

()Bir işlevden sonra kullanmak , işlevi yürütmek ve değerini döndürmek anlamına gelir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.