Soru var functionName = işlev () {} vs işlev functionName () {}


Yakın zamanda başka birinin JavaScript kodunu tutmaya başladım. Hatalar gideriyorum, özellikler ekliyorum ve kodu düzenli hale getirip daha tutarlı hale getirmeye çalışıyorum.

Önceki geliştirici, işlevleri bildirmenin iki yolunu kullanır ve bunun arkasında bir neden varsa çalışamazdım.

İki yol:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

Bu iki farklı yöntemi kullanmanın nedenleri nelerdir ve her birinin artıları ve eksileri nelerdir? Bir diğeriyle yapılamayacak bir yöntemle yapılabilecek bir şey var mı?


6059
2017-12-03 11:31


Menşei


permadi.com/tutorial/jsFunc/index.html Javascript fonksiyonları hakkında çok iyi bir sayfa - uzay95
İlgili bu mükemmel makale Adlandırılmış İşlev İfadeleri. - Phrogz
@CMS bu makaleye referans verir: kangax.github.com/nfe/#expr-vs-decl - Upperstage
Farkında olmanız gereken iki şey vardır: # 1 JavaScript'te bildirimler kaldırılır. Anlamında var a = 1; var b = 2; olur var a; var b; a = 1; b = 2. Yani, bir işlevi bildirdiğinizde, bildirilir, ancak değeri hemen ayarlanmaz. FunctionTwo sadece bir deklarasyon olduğundan, kapsamın en üstünde yer alır. # 2 functionTwo name özelliğine erişmenizi sağlar ve bir şeyleri hata ayıklamaya çalışırken çok yardımcı olur. - xavierm02
Oh ve btw, doğru sözdizimi bir ";" ile atama sonrası ve beyanname olmadan. Örneğin. function f(){} vs var f = function(){};. - xavierm02


Cevaplar:


Fark şu ki functionOne bir işlev ifadesidir ve bu nedenle yalnızca bu satıra ulaşıldığında tanımlanır. functionTwo bir işlev bildirgesidir ve çevreleyen işlevi veya komut dosyası çalıştırıldığında tanımlanır. kaldırma).

Örneğin, bir işlev ifadesi:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

Ve bir işlev bildirimi:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

Bu ayrıca işlev bildirimlerini kullanarak işlevleri koşullu olarak tanımlayamayacağınız anlamına gelir:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

Yukarıdaki aslında tanımlar functionThree ne olursa olsun testdeğeri - değilse use strict etkindir, bu durumda sadece bir hata oluşturur.


4493
2017-12-03 11:37



@Greg: Bu arada, fark sadece farklı zamanlarda ayrıştırıldıkları değil. Aslında, senin functionOnesadece kendisine atanan anonim bir işlevi olan bir değişkendir. functionTwo aslında adlandırılmış bir işlevdir. Aramak .toString() her ikisinde de farkı görmek için. Bu, bazı işlevlerin programsal olarak bir işlev adını almak istediğinizde önemlidir. - Jason Bunting
Her ikisi de farklı. İlki bir function expression ikincisi bir function declaration. Bu konuyla ilgili daha fazla bilgiyi buradan okuyabilirsiniz: javascriptweblog.wordpress.com/2010/07/06/... - Michal Kuklis
@Greg Ayrıştırma zamanı ve çalışma süresi ile ilgili cevabınızın bir kısmı doğru değil. JavaScript'te, işlev bildirimleri ayrıştırma zamanı sırasında değil, çalışma süresi sırasında tanımlanmaz. İşlem şöyle gerçekleşir: Kaynak kodu ayrıştırılır -> JavaScript programı değerlendirilir -> Global yürütme içeriği başlatılır -> bildirim bağlama örneği gerçekleştirilir. Bu işlem sırasında işlev bildirimleri başlatılır (bkz. Bölüm 10.5). - Šime Vidas
Bu fenomenin terminolojisi kaldırma olarak bilinir. - Colin Pear
Bu cevabın Eugene'nin üzerinde hiçbir şeyi yok. Ve parse-time vs run-time deyimiyle oldukça yanıltıcıdır. - Griffin


İlk önce Greg'i düzeltmek istiyorum: function abc(){} çok kapsamlıdır - isim abc Bu tanımın oluştuğu kapsamda tanımlanır. Örnek:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

İkincisi, iki stili birleştirmek mümkündür:

var xyz = function abc(){};

xyz her zamanki gibi tanımlanacak abc tüm tarayıcılarda tanımsızdır, ancak Internet Explorer - tanımlandığından emin olmaz. Ama vücudunun içinde tanımlanacak:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

Tüm tarayıcılarda diğer ad işlevlerini kullanmak istiyorsanız, bu tür bir bildirimi kullanın:

function abc(){};
var xyz = abc;

Bu durumda xyz ve abc aynı nesnenin takma adları:

console.log(xyz === abc); // prints "true"

Kombine stilini kullanmak için tek bir sebep, işlev nesnelerinin "isim" niteliğidir (Internet Explorer tarafından desteklenmiyor). Temel olarak bir işlevi tanımladığınızda

function abc(){};
console.log(abc.name); // prints "abc"

adı otomatik olarak atanır. Ama onu tanımladığınızda

var abc = function(){};
console.log(abc.name); // prints ""

adı boş - anonim bir işlev oluşturduk ve onu bir değişkene atadık.

Birleştirilmiş stili kullanmanın bir başka iyi nedeni, dış kullanıcılar için uzun bir çelişkili olmayan isim sağlarken, kendisine atıfta bulunmak için kısa bir iç ad kullanmaktır:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

Yukarıdaki örnekte, aynı şeyi harici bir adla yapabiliriz, ancak çok hantal olacak (ve daha yavaş).

(Kendisine atıfta bulunmanın başka bir yolu da kullanmaktır. arguments.calleehala nispeten uzun ve sıkı modda desteklenmiyor.)

Derinlemesine, JavaScript iki ifadeyi farklı şekilde ele alır. Bu bir işlev bildirgesidir:

function abc(){}

abc şimdiki kapsamda her yerde tanımlanmıştır:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

Ayrıca, bir return Beyan:

// We can call it here
abc(); // Works
return;
function abc(){}

Bu bir işlev ifadesidir:

var xyz = function(){};

xyz burada atama noktasından tanımlanmıştır:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Fonksiyon beyanı ve fonksiyon ifadesi, Greg tarafından gösterilen bir farkın olmasının gerçek sebebidir.

Eğlenceli gerçek:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Şahsen, "işlev ifadesi" beyanını tercih ederim, çünkü bu şekilde görünürlüğü kontrol edebilirim. İşlevi tanımladığımda

var abc = function(){};

Fonksiyonu yerel olarak tanımladığımı biliyorum. İşlevi tanımladığımda

abc = function(){};

Ben tanımlamamı sağlayarak küresel olarak tanımladığımı biliyorum. abc kapsam zincirinin herhangi bir yerinde. Bu tanım tarzı, içinde kullanıldığında bile esnektir eval(). Tanımı yaparken

function abc(){};

bağlama bağlıdır ve özellikle nerede olduğu, aslında nerede tanımlandığını tahmin etmenize izin verebilir eval() - Cevap: Tarayıcıya bağlı.


1805
2017-12-03 17:43



Ben RoBorg'a başvuruyorum, ama bulunacak bir yer yok. Basit: RoBorg === Greg. Tarih, internet çağında nasıl yeniden yazılabilir. ;-) - Eugene Lazutkin
var xyz = function abc () {}; console.log (xyz === abc); Test ettiğim tüm tarayıcılar (Safari 4, Firefox 3.5.5, Opera 10.10) bana "Tanımlanmamış değişken: abc" veriyor. - NVI
Genel olarak bu yazının, işlev bildiriminin kullanılmasının farklılıklarını ve avantajlarını açıklamak için iyi bir iş olduğunu düşünüyorum. Özellikle "fayda" ifadesinin küresel bir varlığın ilan edilmesinin bir savunucusu olduğu ve özellikle de global ad alanının karıştırılmaması gerektiğini bildikleri için, bir değişkene işlev ifadesi atamalarını kullanmanın yararları arasında anlaşmaya varacağım. , sağ? ;-) - natlee75
imo işlevini kullanmak için büyük bir neden, hata ayıklayıcıların, çağrı yığınınızı veya yığın izlemenizi anlamlandırmanıza yardımcı olması için adı kullanabilmeleridir. Çağrı yığına baktığınızda berbat ve "anonim işlev" 10 seviyesini gör ... - goat
@Antimony Bir işlev bildirimi, bir blokla aynı şey değildir. Bu daha iyi açıklamalıdır: stackoverflow.com/questions/17409945/... - Cypher


İşte, işlevler oluşturan standart formların özetidir: (Başlangıçta başka bir soru için yazılmış, ancak kanonik soruya taşındıktan sonra uyarlanmıştır.)

Şartları:

Hızlı listesi:

  • İşlev Beyanı

  • "Anonim" function ifade (bu terime rağmen, bazen isimlerle fonksiyonlar yaratırlar)

  • adlı function ifade

  • Accessor Function Initializer (ES5 +)

  • Ok İşlev İfadesi (ES2015 +) (Bu, anonim işlev ifadeleri gibi, açık bir ad içermez ve adlarıyla işlevler oluşturabilir)

  • Object Initializer'da (ES2015 +) Yöntem Bildirimi

  • Yapıcı ve Yöntem Bildirimleri class (ES2015 +)

İşlev Beyanı

İlk form bir işlev bildirimiBuna benzeyen:

function x() {
    console.log('x');
}

Bir fonksiyon beyanı deklarasyon; bu bir ifade ya da ifade değil. Bu şekilde, onu bir ; (bunu yaparken de zararsızdır).

Yürütme göründüğü içeriğe girdiğinde bir işlev bildirimi işlenir, önce herhangi bir adım adım kod çalıştırılır. Yarattığı işleve uygun bir isim verilir (x Yukarıdaki örnekte) ve bu ad, bildirimin göründüğü kapsam içine alınır.

Aynı bağlamdaki herhangi bir adım adım koddan önce işlendiği için, şu gibi şeyler yapabilirsiniz:

x(); // Works even though it's above the declaration
function x() {
    console.log('x');
}

ES2015'e kadar, bir JavaScript altyapısının, bir denetim bildirimi gibi bir işlev bildirimi koyarsanız ne yapması gerektiğini kapsamaz. try, if, switch, while, vb, bunun gibi:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

Ve işlendikleri için önce adım adım kod çalıştırılır, bir kontrol yapısında olduklarında ne yapılması gerektiğini bilmek zor olur.

Bunu yapmamakla birlikte belirtildi ES2015'e kadar, bir izin verilen uzantı bloklardaki fonksiyon bildirimlerini desteklemek. Ne yazık ki (ve kaçınılmaz olarak), farklı motorlar farklı şeyler yaptı.

ES2015'ten itibaren, şartname ne yapılacağını söylüyor. Aslında, yapmak için üç ayrı şey verir:

  1. Gevşek modunda ise değil Bir web tarayıcısında, JavaScript motoru bir şey yapması gerekiyordu
  2. Bir web tarayıcısında gevşek modda ise, JavaScript motorunun başka bir şey yapması gerekiyordu.
  3. Eğer varsa sıkı modu (tarayıcı veya değil), JavaScript motoru başka bir şey yapmak gerekiyordu

Gevşek modlar için kurallar zor, ama sıkı mod, bloklardaki fonksiyon bildirimleri kolaydır: bloktan yereldirler ( blok kapsamı, aynı zamanda ES2015'te de yeni) ve bloğun tepesine çekiliyorlar. Yani:

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
                         // because it's not in the same block)

"Anonim" function ifade

İkinci yaygın forma bir denir anonim işlev ifadesi:

var y = function () {
    console.log('y');
};

Tüm ifadeler gibi, kodun adım adım yürütülmesi sırasında ulaşıldığında değerlendirilir.

ES5'te, bu yaratılan işlevin bir adı yoktur (anonimdir). ES2015'te, işlev mümkünse bağlamdan çıkarılarak bir ad verilir. Yukarıdaki örnekte, isim y. Benzer bir özellik, bir özellik başlatıcısının değeri olduğunda yapılır. (Bu olduğunda ve kurallarla ilgili ayrıntılar için, SetFunctionName içinde şartname- görünüyor ki baştan yer.)

adlı function ifade

Üçüncü form bir adlandırılmış işlev ifadesi ( "NFE"):

var z = function w() {
    console.log('zw')
};

Bu yaratılan işlev uygun bir ada sahipw bu durumda). Tüm ifadeler gibi, bu kodun adım adım yürütülmesinde ulaşıldığında değerlendirilir. Fonksiyonun adı değil ifadenin göründüğü kapsama eklendi; isim olduğu kapsam içinde kendi içinde:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

NFE'lerin, JavaScript uygulamaları için sık sık bir hata kaynağı olduğunu unutmayın. IE8 ve daha önceleri, örneğin, NFE'leri ele al tamamen yanlışİki farklı zamanda iki farklı fonksiyon yaratmak. Safari'nin erken sürümlerinde de sorunlar vardı. İyi haber şu ki, tarayıcıların mevcut sürümlerinin (IE9 ve üstü, şu andaki Safari) artık bu sorunları yok. (Ama bu yazıdan dolayı, maalesef, IE8 yaygın kullanımda kalıyor ve bu nedenle web için genel olarak kodlu NFE'lerin kullanılması hala sorunlu.)

Accessor Function Initializer (ES5 +)

Bazen fonksiyonlar büyük ölçüde fark edilmeden gizlenebilir; durum böyle erişim fonksiyonları. İşte bir örnek:

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

Fonksiyonu kullandığımda kullanmadığımı unutmayın. ()! Çünkü bu bir erişim işlevi bir özellik için. Özelliği normal bir şekilde alıp ayarladık, ancak perde arkasından işleve denir.

Ayrıca, Object.defineProperty, Object.definePropertiesve daha az bilinen ikinci argüman Object.create.

Ok İşlev İfadesi (ES2015 +)

ES2015 bizi getiriyor ok işlevi. İşte bir örnek:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

Bunu gör n => n * 2 içinde saklanan şey map() aramak? Bu bir fonksiyon.

Ok fonksiyonları hakkında birkaç şey:

  1. Onların kendileri yok this. Bunun yerine onlar üstünü kapat  this tanımlandıkları bağlamın (Onlar da kapanırlar arguments ve ilgili ise super.) Bu demektir ki this içlerinde olduğu gibi this nerede yaratıldıkları ve değiştirilemezler.

  2. Yukarıdakilerle fark edeceğiniz gibi, anahtar kelimeyi kullanmazsınız function; yerine kullanırsın =>.

n => n * 2 Yukarıdaki örnek, bunların bir şeklidir. Fonksiyonu geçmek için birden fazla argümanınız varsa, parens kullanın:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(Bunu hatırla Array#map girdiyi ilk bağımsız değişken olarak ve ikinci olarak dizin geçirir.)

Her iki durumda da, işlevin gövdesi sadece bir ifadedir; fonksiyonun geri dönüş değeri otomatik olarak o ifadenin sonucu olacaktır (açık kullanmıyorsunuz). return).

Tek bir ifadeden daha fazlasını yapıyorsanız {} ve açık return (bir değer döndürmeniz gerekiyorsa), normal olarak:

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

Olmadan sürümü { ... } bir ok işlevi ile çağrılır ifade gövdesi veya özlü vücut. (Ayrıca bir Özlü ok işlevi.) { ... } Vücudu tanımlamak, işlev gövdesi. (Ayrıca bir gereksiz sözlerle dolu ok işlevi.)

Object Initializer'da (ES2015 +) Yöntem Bildirimi

ES2015, bir işleve başvuran bir özelliği bildirmenin daha kısa bir biçimini sağlar; şuna benziyor:

var o = {
    foo() {
    }
};

ES5 ve daha önceki eşdeğer şu olurdu:

var o = {
    foo: function foo() {
    }
};

Yapıcı ve Yöntem Bildirimleri class (ES2015 +)

ES2015 bizi getiriyor class bildirilen kurucular ve yöntemler dahil olmak üzere sözdizimi:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

Yukarıda iki işlev bildirimi vardır: Adını alan kurucu için Personve bir tane için getFullName, atanan bir işlevdir Person.prototype.


544
2018-03-04 13:35



sonra isim w basitçe göz ardı edilir mi? - BiAiB
@PellePenna: İşlev isimleri bir çok şey için yararlıdır. Benim görüşümdeki iki bisiklet, özyineleme ve çağrı yığınlarında, istisna izlerinde ve bu işlevlerde gösterilen işlevin adıdır. - T.J. Crowder
Bu şimdi kabul edilen cevap olmalı. Yukarıdakilerden çok daha yeni. - Chaim Eliyah
@ChaimEliyah - "Kabul etmek en iyi cevap olduğu anlamına gelmez, sadece sorduğu kişi için çalıştığı anlamına gelir." kaynak - ScrapCode
@ A.R .: Oldukça doğru. Yine de, bunun tam tersine, “En iyi cevaplar ilk önce ortaya çıkar, böylece her zaman kolay bulunurlar” diyor. Kabul edilen cevap ilk olarak daha yüksek oyu alan cevaplar üzerinde ortaya çıktığından, tur biraz çelişkili olabilir. ;-) Ayrıca, "oylama" sekmesini kullanıyorsanız, "en iyi" oyları (ki bu güvenilir değil, sadece sahip olduğumuz şey), "en iyi" yanıtları belirlediğimizde biraz da doğru değil. - Aksi takdirde, ilk cevaplar aktif olan veya en eski olanlardır. - T.J. Crowder


Küresel bağlam hakkında konuşma, her ikisi de var deyim ve bir FunctionDeclaration sonunda bir olmayan bir silinebilir global nesnedeki özellik, ancak her ikisinin değeri üzerine yazılabilir.

İki yol arasındaki ince fark, Değişken Örnekleme işlem (gerçek kod çalıştırmadan önce) ile bildirilen tüm tanımlayıcılar var ile başlatılacak undefinedve tarafından kullanılan FunctionDeclarationO andan itibaren mevcut olacak, örneğin:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

Atama bar  FunctionExpression çalışma zamanına kadar yer alır.

Tarafından oluşturulan global özellik FunctionDeclaration değişken bir değer gibi herhangi bir sorun olmadan üzerine yazılabilir, örn .:

 function test () {}
 test = null;

İki örneğiniz arasındaki bir diğer belirgin fark, ilk fonksiyonun bir isme sahip olmamasıdır, ancak ikincisi buna sahiptir, bu da hata ayıklaması yaparken (yani çağrı yığınının incelenmesi) gerçekten faydalı olabilir.

Düzenlenmiş ilk örnek hakkında (foo = function() { alert('hello!'); };), beyan edilmemiş bir görevdir, sizi her zaman kullanmaya teşvik ederim. var Anahtar kelime.

Atama olmadan var deyim, başvurulan tanımlayıcı kapsam zincirinde bulunmazsa, bir bir silinebilir genel nesnenin özelliği.

Ayrıca, beyan edilmemiş ödevler ReferenceError ECMAScript 5 altında Sıkı mod.

Okunmalı:

Not: Bu cevap birleştirilmiş başka bir soruOP'den gelen en büyük şüphe ve yanlış anlaşılmanın tanımlayıcıların bir FunctionDeclaration, böyle bir durumun üzerine yazılmadı.


133
2017-08-08 19:32



JavaScript'te işlevlerin üzerine yazılabileceğini bilmiyordum! Ayrıca, bu ayrıştırma düzeni benim için büyük satış noktasıdır. Sanırım fonksiyonları nasıl oluşturduğumu izlemem gerek. - Xeoncross
404ing olarak "İsimler işlev ifadeleri demystified" makalesine +0. Olası ayna ?: kangax.github.com/nfe - Mr_Chimp
@CMS Güzel biri. Orijinali hiç görmesem de akılda tutun, bu yüzden ayna mı yoksa aynı başlık ile başka bir makale mi bilmiyorum! - Mr_Chimp
@Mr_Chimp Oldukça eminim, waybackmachine tarama süresinde 302 olduğunu ve yönlendirmenin sağladığınız bağlantıya olduğunu söylüyor. - John


Orada gönderdiğiniz iki kod parçacığı, neredeyse tüm amaçlar için aynı şekilde davranır.

Ancak davranıştaki fark, ilk değişkenle (var functionOne = function() {}), bu işlev sadece kodda bu noktadan sonra çağrılabilir.

İkinci varyantla (function functionTwo()) işlev, işlevin bildirildiği yerde çalışan kod için kullanılabilir.

Bunun nedeni, ilk varyantla, fonksiyon değişkene atanmasıdır foo işlem esnasında. İkincisi, işlev o tanımlayıcıya atanır, foo, ayrıştırma zamanında.

Daha fazla teknik bilgi

JavaScript'in işlevleri tanımlamanın üç yolu vardır.

  1. İlk snippet'iniz bir işlev ifadesi. Bu kullanarak içerir "işlev" operatörü Bir işlev oluşturmak için - bu operatörün sonucu herhangi bir değişken veya nesne özelliğinde saklanabilir. Fonksiyon ifadesi bu şekilde güçlüdür. İşlev ifadesi genellikle "anonim işlev" olarak adlandırılır, çünkü bir adı olması gerekmez.
  2. İkinci örneğiniz bir işlev bildirimi. Bu kullanır "işlev" ifadesi Bir işlev oluşturmak için. İşlev ayrıştırma zamanında kullanılabilir ve bu kapsamda herhangi bir yere çağrılabilir. Bunu daha sonra bir değişken veya nesne özelliğinde saklayabilirsiniz.
  3. Bir fonksiyonu tanımlamanın üçüncü yolu; "İşlev ()" yapıcısıOrijinal yayında gösterilmiyor. Bunu aynı şekilde çalıştığı için kullanılması önerilmez. eval()Onun sorunları var.

111
2018-04-20 04:54





Daha iyi bir açıklama Greg'in cevabı

functionTwo();
function functionTwo() {
}

Neden hata yok? Her zaman ifadelerin yukarıdan aşağıya doğru yürütüldüğünü öğrettik (??)

Çünkü:

İşlev bildirimleri ve değişken bildirimler her zaman taşınır (hoisted) Javascript yorumlayıcısı tarafından içerdikleri kapsamın üstüne görünmez şekilde. İşlev parametreleri ve dil tanımlı adlar, zaten oradadır. ben kiraz

Bu şu gibi kod anlamına gelir:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

Bildirimlerin atama bölümünün kaldırılmadığına dikkat edin. Sadece isim kaldırılır.

Ancak işlev bildirimleriyle birlikte, tüm işlev gövdesi de kaldırılacaktır.:

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

91
2017-08-09 02:45



HI suhail Fonksiyon konusu hakkında net bilgi için teşekkürler. Şimdi benim sorum olan deklarasyon hiyerarşisinde ilk deklarasyon hangisinin değişken bildirim (functionOne) veya işlev bildirimi (functionTwo) olup olmadığıdır? - Sharathi RB


Diğer yorumcular, yukarıdaki iki varyantın anlamsal farkını zaten kapatmışlardır. Bir stilistik fark belirtmek istedim: Sadece "atama" varyasyonu başka bir nesnenin bir özelliğini ayarlayabilir.

Bu gibi bir modelle sık sık JavaScript modülleri yapıyorum:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

Bu modelde, genel işlevleriniz bildirim kullanırken tüm özel işlevleriniz atama kullanır.

(Beyannamenin yasaklanmasına rağmen, bildirimin ardından bir noktalı virgül gerektirmesi gerektiğini de unutmayın.)


83
2018-03-03 19:19



yuiblog.com/blog/2007/06/12/module-pattern söyleyebileceğim kadarıyla modül kalıbı için ilk referanstır. (Bu makalede var foo = function(){...} özel değişkenler için bile sözdizimi. - Sean McMillan
Aslında, IE'nin bazı eski sürümlerinde bu tamamen doğru değil. (function window.onload() {} bir şeydi.) - Ry-♦


İlk yöntemin ne zaman ikincisini tercih edeceğinin bir örneği, bir fonksiyonun önceki tanımlarını geçersiz kılmaktan kaçınmanız gerektiğidir.

İle

if (condition){
    function myfunction(){
        // Some code
    }
}

, bu tanım myfunction ayrıştırma zamanında yapılacağından önceki herhangi bir tanımı geçersiz kılar.

Süre

if (condition){
    var myfunction = function (){
        // Some code
    }
}

tanımlamanın doğru işi myfunction Yalnızca condition karşılandı.


68
2018-03-29 13:26



Bu örnek iyidir ve mükemmelliğe yakındır, ancak geliştirilebilir. daha iyi örnek tanımlanacaktı var myFunc = null; Bir döngü dışında veya if / elseif / else bloğu dışında. Daha sonra aynı değişkene farklı işlevler şartlı olarak atayabilirsiniz. JS'de, null'a, sonra undefined'e eksik bir değer atamak daha iyi bir konudur. Bu nedenle, ilk önce işlevimi null olarak bildirmeli ve daha sonra koşullu olarak atamalısınız. - Alexander Mills


Önemli bir sebep, ad alanınızın "Kökü" olarak bir ve tek değişken eklemek.

var MyNamespace = {}
MyNamespace.foo= function() {

}

veya

var MyNamespace = {
  foo: function() {
  },
  ...
}

İsim yazmak için birçok teknik var. Mevcut JavaScript modüllerinin bolluğu ile daha da önemli hale geliyor.

Ayrıca bkz. JavaScript'te bir ad alanını nasıl bildiririm?


55
2017-08-08 19:44



Bu cevap, bu soruya başka bir sorudan ve ifadeden aktarılmış gibi görünüyor. belki ilgisi olmayan küçük bir şey gibi görünüyor bu soru. Cevabı düzenlemeyi düşünür müsünüz, özellikle bu soruya daha çok yöneltilmiş görünüyor mu? (tekrarlamak için; bu hiç de senin suçun değil ... birleşik bir sorunun sadece bir yan etkisi). Onu da silebilirsin ve bence itibarını koruyacaksın. Ya da bırakabilirsiniz; eski olduğu için büyük bir fark yaratmayabilir. - Andrew Barber


kaldırma  JavaScript yorumcusunun, tüm değişken ve işlev bildirimlerini geçerli kapsamın en üstüne taşıması eylemidir. 

Ancak, sadece gerçek beyanlar kaldırılır. oldukları yerde ödevler bırakarak.

  • Sayfanın içinde bildirilen değişkenin / İşlevler, genel olarak bu sayfadaki herhangi bir yere erişebilir.
  • işlev içinde bildirilen değişkenler / İşlevler yerel kapsamı vardır. işlev gövdesinde (kapsam) erişilebilir / erişilebilir oldukları anlamına gelir, bunlar işlev gövdesinin dışında kullanılabilir değildir.

Değişken

Javascript gevşek yazılmış bir dil denir. Bu, Javascript değişkenlerinin herhangi birinin değerini tutabileceği anlamına gelir Veri tipi. Javascript, çalışma zamanı sırasında sağlanan değere / literal değere bağlı olarak değişken türünü değiştirmeye otomatik olarak bakar.

global_Page = 10;                                               var global_Page;      « undefined
    « Integer literal, Number Type.   -------------------       global_Page = 10;     « Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; « String
    « String literal, String Type.    «       AS        «       global_Page = true;   « Boolean 
var global_Page = true;               |                 |       global_Page = function (){          « function
    « Boolean Type                    -------------------                 var local_functionblock;  « undefined
global_Page = function (){                                                local_functionblock = 777;« Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

fonksiyon

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      « return;  Default undefined
      « return 'some data';
}
  • Sayfa içinde bildirilen işlevler, sayfanın üst kısmına küresel erişime sahip olacak şekilde kaldırılır.
  • Fonksiyon bloğu içinde beyan edilen fonksiyonlar bloğun tepesine çekilir.
  • Fonksiyonun varsayılan dönüş değeri 'Tanımsız' Değişken bildirim varsayılan değeri de 'undefined'

    Scope with respect to function-block global. 
    Scope with respect to page undefined | not available.
    

İşlev Beyanı

function globalAccess() {                                  function globalAccess() {      
}                                  -------------------     }
globalAccess();                    |                 |     function globalAccess() { « Re-Defined / overridden.
localAccess();                     «   Hoisted  As   «         function localAccess() {
function globalAccess() {          |                 |         }
     localAccess();                -------------------         localAccess(); « function accessed with in globalAccess() only.
     function localAccess() {                              }
     }                                                     globalAccess();
}                                                          localAccess(); « ReferenceError as the function is not defined

İşlev İfadesi

        10;                 « literal
       (10);                « Expression                (10).toString() -> '10'
var a;                      
    a = 10;                 « Expression var              a.toString()  -> '10'
(function invoke() {        « Expression Function
 console.log('Self Invoking');                      (function () {
});                                                               }) () -> 'Self Invoking'

var f; 
    f = function (){        « Expression var Function
    console.log('var Function');                                   f ()  -> 'var Function'
    };

Değişkene atanan işlev Örnek:

(function selfExecuting(){
    console.log('IIFE - Immediately-Invoked Function Expression');
}());

var anonymous = function (){
    console.log('anonymous function Expression');
};

var namedExpression = function for_InternalUSE(fact){
    if(fact === 1){
        return 1;
    }

    var localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    //return; //undefined.
    return fact * for_InternalUSE( fact - 1);   
};

namedExpression();
globalExpression();

javascript olarak yorumlandı

var anonymous;
var namedExpression;
var globalExpression;

anonymous = function (){
    console.log('anonymous function Expression');
};

namedExpression = function for_InternalUSE(fact){
    var localExpression;

    if(fact === 1){
        return 1;
    }
    localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
};

namedExpression(10);
globalExpression();

Farklı tarayıcıların kullanarak ifade bildirimini ve ifade testini kontrol edebilirsiniz. jsperf Test Runner


ES5 Oluşturucu İşlev Sınıfları: Function.prototype.bind kullanılarak oluşturulan işlev nesneleri

JavaScript fonksiyonları birinci sınıf nesneler olarak değerlendirir, böylece bir nesne olarak bir işleve özellik atayabilirsiniz.

function Shape(id) { // Function Declaration
    this.id = id;
};
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };

var expFn = Shape; // Function Expression

var funObj = new Shape( ); // Function Object
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 );
console.log( funObj.getID() ); // 10

ES6 tanıtıldı Ok fonksiyonu: Bir ok işlevi ifadesinin kısa bir sözdizimi vardır, bunlar yöntem dışı işlevler için en uygunudur ve kurucular olarak kullanılamazlar.

ArrowFunction : ArrowParameters => ConciseBody.

const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd

47
2018-01-25 14:46



ahm, cevabın ... belirsiz değil mi? iyi yazılmış olsa da çok fazla bilgi ve harcama için +1 yazdı. - Danish