Var functionName = function () {} vs function functionName () {}

Son zamanlarda, başka bir kullanıcının JavaScript kodunu desteklemeye başladım. Hataları düzeltir, işlevler eklerim ve ayrıca kodu düzeltmeye ve daha tutarlı hale getirmeye çalışırım.

Önceki geliştirici, işlevleri bildirmek için iki yol kullanıyor ve bunun bir nedeni olup olmadığını çözemiyorum.

İki yol:

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

Bu iki farklı yöntemi kullanmanın nedenleri ve bunların her birinin artıları ve eksileri nelerdir? Başka bir yöntemle yapılamayan bir yöntemle yapılabilecek bir şey var mı?

6296
03 дек. Richard Garside 03 Aralık istedi 2008-12-03 14:31 '08, 02:31, 2008-12-03 14:31
@ 37 cevaplar
  • 1
  • 2

Aradaki fark, functionOne bir fonksiyonun ifadesi olmasıdır ve bu nedenle yalnızca bu satıra ulaşıldığında belirlenir, ancak functionTwo bir fonksiyon bildirimidir ve etrafındaki fonksiyonu veya komut dosyası çalıştırıldığında ( kaldırma nedeniyle) belirlenir.

Örneğin, ifade işlevi:

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

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

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

Yukarıdakiler aslında test değeri ne olursa olsun functionThree tanımlar - use strict eylem olmadıkça, bu durumda sadece bir hataya neden olur.

4669
03 дек. Tarafından cevap cevap Greg 03 dec. 2008-12-03 14:37 '08, 02:37, 2008-12-03 14:37

İlk önce Greg'i düzeltmek istiyorum: function abc(){} ayrıca sınırlıdır; - abc ismi bu tanımın bulunduğu alanda tanımlanmıştır. örnek:

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

İkincisi, her iki stili de birleştirebilirsiniz:

 var xyz = function abc(){}; 

xyz her zamanki gibi tanımlanır, abc - tüm tarayıcılarda tanımsızdır, ancak Internet Explorer - tanımına bağlı değildir. Ama vücudunda 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 takma adlar kullanmak istiyorsanız, bu reklam türünü kullanın:

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

Bu durumda, hem xyz hem de abc aynı nesnenin diğer xyz :

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

Birleştirilmiş stili kullanmanın en zorlayıcı nedenlerinden biri, işlev nesneleri için "name" niteliğidir ( Internet Explorer tarafından desteklenmez ). Temel olarak, gibi bir işlevi tanımladığınızda

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

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

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

onun adı boş - biz isimsiz bir fonksiyon yarattık ve ona değişken olarak atadık.

Birleştirilmiş stili kullanmanın bir başka iyi nedeni, dış kullanıcılar için uzun bir çelişkili ad sağlayarak, ona 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, dış adla aynı şeyi yapabiliriz, ancak çok hantal (ve daha yavaş) olur.

(Kendinizi ele almanın başka bir yolu, hala nispeten uzun olan ve katı modda desteklenmeyen arguments.callee kullanmaktır.)

Aşağı, JavaScript her iki ifadeyi de farklı şekilde ele alır. Bu bir işlev bildirimidir:

border=0
 function abc(){} 

abc burada mevcut alanda 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 

Buna ek olarak, return kullanarak yükseldi:

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

Bu bir fonksiyon ifadesidir:

 var xyz = function(){}; 

xyz burada hedeften tanımlanır:

 // We can't call it here xyz(); // UNDEFINED!!! // Now it is defined xyz = function(){} // We can call it here xyz(); // works 

İşlev bildirimi ve işlev ifadesi, Greg tarafından gösterilen bir farkın gerçek nedenidir.

Eğlenceli gerçek:

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

Şahsen, ben "işlev ifadesi" bildirimini tercih ederim çünkü bu şekilde görünürlüğü kontrol edebiliyorum. Bir yazım işlevi tanımladığımda

 var abc = function(){}; 

Fonksiyonu yerel olarak tanımladığımı biliyorum. Bir yazım işlevi tanımladığımda

 abc = function(){}; 

Bunu küresel olarak tanımladığımı, bölge zincirinde hiçbir yerde abc tanımlamadığımı belirttiğimi biliyorum. Bu tanım tarzı, eval() içinde kullanıldığında bile kararlıdır. Tanımı olmasına rağmen

 function abc(){}; 

Bağlama bağlıdır ve özellikle eval() durumunda, nerede tanımlandığını merak etmenize izin verebilir - Cevap: Tarayıcıya bağlıdır.

1846
03 дек. Cevap Eugene Lazutkin 03 Aralık tarafından verilmiştir . 2008-12-03 20:43 '08, 08:43, 2008-12-03 20:43

İşlevleri oluşturan standart formların bir özeti: (Aslen başka bir soru için yazılmış, ancak kanonik soruya geçişten sonra uyarlanmış.)

terimleri:

Hızlı liste:

  • İşlev bildirimi

  • "Anonim" function İfadesi (Terime rağmen bazen adlarla işlevler oluşturur)

  • Adlandırılmış function İfade

  • Erişim Fonksiyonu Başlatıcısı (ES5 +)

  • Ok işlevi ifadesi (ES2015 +) (adsız işlev ifadeleri gibi açık bir ad içermez ve adlarla işlevler oluşturabilir)

  • Nesne başlatıcıda yöntem bildirimi (ES2015 +)

  • class yapıcı ve yöntem bildirimleri (ES2015 +)

İşlev bildirimi

İlk form, şuna benzeyen bir işlev bildirimidir:

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

Bir işlev bildirimi bir reklamdır; bu bir ifade veya ifade değildir. Demek onu takip etmiyorsun ; (zararsız olmasına rağmen).

Yürütme, herhangi bir adım kodunu yürütmeden önce göründüğü içeriğe girdiğinde, bir işlev bildirimi işlenir. Yarattığı işleve kendi adı verilir (yukarıdaki örnekte x ) ve bu ad bildirimin göründüğü alana yerleştirilir.

Aynı bağlamda herhangi bir adım kodundan önce işlendiğinden, bunun gibi bir şey yapabilirsiniz:

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

ES2015'ten önce, bir kontrol yapısının içine bir işlev bildirimi yerleştirdiyseniz, örneğin, JavaScript motorunun ne yapması gerektiği belirtilmemiştir, örneğin, try , if , geç, vb.

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

Adım adım kodu çalıştırmadan önce işlendiklerinden, yönetim yapısında ne yapacaklarını bilmek zordur.

ES2015'ten önce belirtilmemiş olmasına rağmen, bloklardaki işlev bildirimlerini desteklemek için geçerli bir uzantıydı. Ne yazık ki (ve kaçınılmaz olarak), farklı motorlar farklı şeyler yaptı.

ES2015 ile başlayarak, teknik özellik ne yapılması gerektiğini söylüyor. Aslında, üç ayrı eylem verir:

  1. Serbest modda web tarayıcısında değilse, JavaScript motoru bir şey yapmalıdır.
  2. Bir web tarayıcısında serbest modda ise, JavaScript motorunun başka bir şey yapması gerekir.
  3. Sıkı modda ise (tarayıcı ya da değil), JavaScript motoru bir şey daha yapmalıdır.

Serbest modlar için kurallar zordur, ancak katı modda, bloklardaki işlev bildirimleri basittir: blokta yereldirler (ES2015'te de yeni olan blok kapsamına sahiptirler) ve bloğa giderler. böylece:

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

İfade "anonim" function

İkinci ortak form, isimsiz bir fonksiyon ifadesi olarak adlandırılır:

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

Tüm ifadeler gibi, adım adım kod çalıştırmaya erişildiğinde de hesaplanır.

ES5'te, oluşturulan işlevin adı yoktur (adsızdır). ES2015'te, mümkün olduğunda bağlam dışına çıkarılarak bir fonksiyona bir ad atanır. Yukarıdaki örnekte, isim y olacaktır. Böyle bir şey, işlev özellik başlatıcının değeri olduğunda ortaya çıkar. (Bunun ne zaman gerçekleştiği ve kurallar hakkında daha fazla bilgi için, belirtimde SetFunctionName bulun - her yerde görünür.)

Adlandırılmış function İfade

Üçüncü biçim, adlandırılmış işlevli ("NFE") bir ifadedir:

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

Yarattığı işlevin kendi adı vardır (bu durumda, w ). Tüm ifadeler gibi, bu adım adım kod yürütme ile gerçekleştirildiğinde değerlendirilir. İşlev adı, ifadenin göründüğü alana eklenmez; isim, işlevin kapsamı dahilindedir:

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

Lütfen NFE'lerin JavaScript uygulamaları için bir hata kaynağı olduğunu unutmayın. Örneğin, IE8 ve önceki sürümler NFE'yi tamamen yanlış kullanır , zaman içinde iki farklı noktada iki farklı fonksiyon oluşturur. Safari'nin ilk sürümlerinde de sorunlar vardı. İyi haber şu ki, tarayıcıların mevcut sürümlerinde (IE9 ve üstü, mevcut Safari), bu tür sorunlar artık mevcut değil. (Fakat ne yazık ki, bu yazının yazıldığı sırada, IE8 hala yaygın olarak kullanılıyor ve bu nedenle NFE'yi bir bütün olarak İnternet koduyla kullanmak hala sorunlu.)

Erişim Fonksiyonu Başlatıcısı (ES5 +)

Bazen işlevler büyük ölçüde farkedilmeden nüfuz edebilir; erişim fonksiyonlarından ne haber? İş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" 

Lütfen, işlevi kullandığımda () kullanmadığımı unutmayın. Bunun nedeni bir özellik için bir erişim işlevi olmasıdır. Özelliği her zamanki gibi alıyoruz ve ayarlıyoruz, ancak perde arkasına bir fonksiyon deniyor.

Object.defineProperty , Object.defineProperties ve daha az bilinen ikinci Object.create bağımsız değişkenini kullanarak erişim işlevleri de oluşturabilirsiniz.

Ok işlevi ifadesi (ES2015 +)

ES2015 bize ok işlevini getiriyor. İşte bir örnek:

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

map() çağrısında n => n * 2 gizli olduğunu görün? Bu bir fonksiyondur.

Okların işlevleri hakkında bir kaç şey:

  1. Bunun kendileri yok. Bunun yerine, tanımlandıkları this bağlamı kapatırlar. (Ayrıca arguments da yakınlar ve uygunsa, super .) Bu, onların içinde olduğu, yaratıldıkları ve değiştirilemeyecekleri anlamına gelir.

  2. Yukarıda belirttiğiniz gibi, anahtar kelimenin function kullanmıyorsunuz; bunun yerine, => kullanın.

Örnek n => n * 2 yukarıdakilerden biridir. Bir işlevi iletmek için birkaç argüman varsa, parens kullanırsınız:

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

(Unutmayın, Array#map , kaydı ilk argüman olarak ve dizini ikinci olarak geçirir.)

Her iki durumda da, işlev gövdesi yalnızca bir ifadedir; işlevin dönüş değeri otomatik olarak bu ifadenin sonucu olacaktır (açık bir return kullanmazsınız).

Birden fazla ifadeden fazlasını yaparsanız, her zamanki gibi {} ve açık bir return (bir değer döndürmeniz gerekirse):

 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)); 

{... } olmayan bir sürüme, ifade gövdesi veya kısa gövdeli bir ok işlevi denir. (Ayrıca: Okun kısa işlevi.) Bedeni tanımlayan {... } işaretli işlev, okun işlev gövdesiyle işlevidir. (Ayrıca: fiil ok işlevi.)

Nesne başlatıcıda yöntem bildirimi (ES2015 +)

ES2015, yöntem tanımı olarak adlandırılan bir işlevi ifade eden daha kısa bir özellik bildirimi formu sağlar; şuna benziyor:

 var o = { foo() { } }; 

ES5 ve önceki sürümlerde neredeyse eşdeğer:

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

Fark (ayrıntılandırma hariç), yöntemin super kullanabilmesidir, ancak işlev kullanamaz. Bu nedenle, örneğin, bir yöntemin sözdizimini kullanarak valueOf değerini tanımlayan (söyleyen) bir nesneniz varsa, döndürülmesi gereken Object.prototype.valueOf değerini almak için super.valueOf() işlevini kullanabilir (sözde bir şey yapmadan önce) onunla başka bir şey), ES5 Sürümünün bunun yerine Object.prototype.valueOf.call(this) , Object.prototype.valueOf.call(this) yapması gerekirdi.

Bu aynı zamanda, yöntemin tanımlandığı nesneye bir referansı olduğu anlamına gelir, bu nedenle, eğer bu nesne geçici ise (örneğin, onu orijinal nesnelerden biri olarak Object.assign ), yöntemin sözdizimi, nesnenin kaydedildiği anlamına gelir. bellek, aksi takdirde çöp toplayıcı tarafından toplanabiliyorsa (JavaScript motoru bu durumu algılamıyorsa ve yöntemlerden hiçbiri super kullanmıyorsa, super ).

class yapıcı ve yöntem bildirimleri (ES2015 +)

ES2015, bildirilen yapıcılar ve yöntemler dahil, bize class sözdizimini sağlar:

 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: Biri Person adında getFullName için, ve getFullName getFullName atanan bir işlev olan Person.prototype için Person.prototype .

574
04 марта '14 в 16:35 2014-03-04 16:35 Cevap TJ Crowder tarafından 04 Mart 14:35 saat 16:35 tarihinde verilmiştir 2014-03-04 16:35

Global bağlamdan bahsetmek gerekirse, hem var hem de FunctionDeclaration ifadeleri, global nesne için silinemez bir özellik oluşturur, ancak her ikisinin de değerinin üzerine yazılabilir.

İki yol arasındaki ince fark, Değişken Örnekleme işlemine başladığında (gerçek kod yürütülmesinden önce), var ile bildirilen tüm tanımlayıcıların undefined olarak başlatılacağı ve şu anda örneğin FunctionDeclaration tarafından kullanılanların kullanılacağıdır:

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

bar FunctionExpression atanması, yürütmeden önce yapılır.

FunctionDeclaration tarafından oluşturulan global özellik, bir değişkenin değeriyle aynı şekilde sorunsuz şekilde üzerine yazılabilir, örneğin:

  function test () {} test = null; 

İki örneğiniz arasındaki bir diğer belirgin fark, ilk işlevin bir adı olmaması, ikincisi de hata ayıklama işleminde (örneğin, çağrı yığınını denetleme) gerçekten yararlı olabilecek ikinci bir farkı var.

Düzenlenen ilk örnek hakkında ( foo = function() { alert('hello!'); }; ), Bu bildirilmemiş bir iştir, her zaman var anahtar kelimesini kullanmanızı şiddetle tavsiye ederim.

Bir var operatörü olmadan atandığında, referans tanımlayıcı kapsam zincirinde bulunmazsa, global nesnenin çıkarılabilir özelliği olacaktır.

Ek olarak, bildirilmemiş görevler Sıkı Mod'da ECMAScript 5'e bir ReferenceError atar.

A okumalısınız:

Not : Bu cevap, OP'nin temel şüphesinin ve yanlış algılanmasının, bir FunctionDeclaration ile bildirilen tanımlayıcıların üzerine yazılamadığı, durum böyle olmadığı üzerine bir başka sorudan birleştirildi.

137
08 авг. Cevap CMS 08 Ağustos tarafından verilir . 2010-08-08 22:32 '10, 10:32 2010-08-08 22:32

Buraya koyduğunuz iki kod parçacığı hemen hemen tüm amaçlar için aynı şekilde davranacak.

Bununla birlikte, davranıştaki fark, ilk seçenekle ( var functionOne = function() {} ) bu fonksiyonun yalnızca koddaki bu noktadan sonra çağrılabilmesidir.

İkinci varyantta ( function functionTwo() ), fonksiyonun bildirildiği, yukarıda yürütülen kod için işlev kullanılabilir.

Bunun nedeni, ilk değişkende işlevin çalışma zamanında foo değişkenine atanmasıdır. İkinci fonksiyonda, bu tanımlayıcı ayrıştırma sırasında foo'ya atanır.

Ek teknik bilgi

JavaScript'in fonksiyonları tanımlamanın üç yolu vardır.

  • İlk snippet'inizde, işlev ifadesi gösterilir. Bunun nedeni bir işlev oluşturmak için "işlev" işlecinin kullanılmasıdır - bu işlecin sonucu herhangi bir değişkende veya nesnede saklanabilir. İşlev ifadesi çok güçlü. Bir işlev ifadesine genellikle "adsız işlev" denir, çünkü bir adı olmamalıdır,
  • İkinci örnek bir işlev bildirimidir. . Bir işlev oluşturmak için "function" operatörünü kullanın. İşlev ayrıştırma sırasında sağlanır ve bu alanda herhangi bir yere çağrılabilir. Daha sonra bir değişkene veya nesneye kaydedebilirsiniz.
  • Bir fonksiyonu tanımlamanın üçüncü yolu, orijinal mesajda gösterilmeyen "Function ()" yapıcısıdır. Bunu kullanmak tavsiye edilmez, çünkü kendi problemleri olan eval() aynı şekilde çalışır.
115
20 апр. Cevap thomasrutter 20 Nis tarafından verildi. 2010-04-20 07:54 '10 7:54 2010-04-20 07:54

Greg en iyi açıklamayı cevapladı

 functionTwo(); function functionTwo() { } 

Neden böcek yok? Her zaman ifadelerin yukarıdan aşağıya doğru yürütüldüğü bize öğretildi (??)

Çünkü:

JavaScript açıklamaları kullanarak işlev bildirimleri ve değişken bildirimleri her zaman görünmez bir şekilde bölgelerinin üstüne taşınır ( hoisted ). Açıkçası, fonksiyonel parametreler ve dil adları zaten var. ben kiraz

Bu, böyle bir kod anlamına gelir:

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

Lütfen bildirimlerin atama kısmının yükseltilmediğini unutmayın. Sadece isim yükseltildi.

Ancak, işlev bildirimleri durumunda, tüm işlevin gövdesi de yükseltilecektir:

 functionTwo(); --------------- function functionTwo() { | is actually | }; function functionTwo() { | interpreted |--> } | like | functionTwo(); --------------- 
96
09 авг. Cevap basit_human 09 ağustos . 2014-08-09 05:45 14, 05:45, 2014-08-09 05:45

Diğer yorumcular, yukarıda listelenen iki seçenek arasındaki anlamsal farkı çoktan değerlendirmişlerdir. Stilistik bir farklılığa işaret etmek istiyorum: sadece bir "hedef" varyasyonu başka bir nesnenin özelliğini belirleyebilir.

Sık sık bu modelle JavaScript modülleri oluşturuyorum:

 (function(){ var exports = {}; function privateUtil() { ... } exports.publicUtil = function() { ... }; return exports; })(); 

Bu şablonu kullanarak, genel işlevleriniz hedefi kullanır, özel işlevleriniz ise reklamı kullanır.

(Ayrıca, ödevin talimattan sonra bir noktalı virgül içermesi gerektiğine dikkat edin.

87
03 марта '11 в 22:19 2011-03-03 22:19 03:11 Mart'ta Sean McMillan'a 22:19 2011-03-03 22:19 tarihinde yanıtladı

İkincisi için ilk yöntemi ne zaman kullanmanın daha iyi olduğunun bir örneği, önceki tanımların işlevlerini geçersiz kılmaktan kaçınmanız gerektiğine ilişkindir.

C

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

bu tanım myfunction ayrıştırma sırasında çalıştırılacağından önceki tanımları geçersiz kılar.

iken

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

myfunction tanımlamak için doğru işi ancak condition yürütüldüğünde yapar.

73
29 марта '13 в 16:26 2013-03-29 16:26 Cevap Mbengue Assane tarafından 29 Mart 13: 16:26 2013-03-29 16:26

Önemli bir neden, ad alanınızın “kökü” olarak bir ve sadece bir değişkenin eklenmesidir ...

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

veya

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

Ad alanı için pek çok yöntem var. Bu, mevcut birçok JavaScript modülüyle daha da önem kazanıyor.

Ayrıca bakınız : Javascript'te isim alanı nasıl bildirilir?

59
08 авг. Cevap Rob 08 Ağustos tarafından verilir . 2010-08-08 22:44 '10, 10:44 PM 2010-08-08 22:44

Kaldırma , tüm değişken ve işlev bildirimlerini geçerli kapsamın baş>

Ancak, yalnızca gerçek bildirimler yükseltilir. görevlerini oldukları yerde bırakarak.

  • Sayfa içinde bildirilen bir değişken / fonksiyon, bu sayfada herhangi bir yere erişim için küresel olarak mevcuttur.
  • переменные/функции, объявленные внутри функции, имеют локальную область. означает, что они доступны/доступны внутри тела функции (scope), они недоступны вне тела функции.

Variable

Javascript называется свободно типизированным языком. Это означает, что переменные Javascript могут содержать значение любого Data-Type . Javascript автоматически позаботится об изменении типа переменной на основе значения/литерала, предоставленного во время выполнения.

 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. }; 

Функция

 function Identifier_opt ( FormalParameterList_opt ) { FunctionBody | sequence of statements « return; Default undefined « return 'some data'; } 
  • функции, объявленные внутри страницы, поднимаются на верх страницы, имеющей глобальный доступ.
  • функции, объявленные внутри функционального блока, поднимаются до вершины блока.
  • Возвращаемое значение по умолчанию функции: undefined ', Variable значение по умолчанию объявления также 'undefined'

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

Объявление функции

 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 

Выражение функции

  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' };