Var functionName = function () {} funksiyası functionName () {}

Son vaxtlarda başqa istifadəçinin JavaScript kodunu dəstəkləməyə başladım. Mən səhvləri düzəltirəm, funksiyalar əlavə etdim və kodu düzəltməyə və daha ardıcıl etməyə çalışıram.

Əvvəlki geliştirici funksiyaları bəyan etmək üçün iki yoldan istifadə edir və bunun bir səbəbi olub olmadığını müəyyən edə bilmirəm.

İki yol:

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

Bu iki fərqli üsuldan istifadə edilməsinin səbəbləri nədir və onların hər birinin mənfəət və istəkləri nədir? Başqaları ilə edilə bilməyən bir üsulla edilə bilən bir şey varmı?

6296
03 дек. Richard Garside soruşdular 03 dekabr 2008-12-03 14:31 '08 at 2:31 pm 2008-12-03 14:31
@ 37 cavab
  • 1
  • 2

Fərq functionOne bir funksiyanın ifadəsidir və buna görə də yalnız bu xəttə çatdıqda təyin olunur, functionTwo isə bir funksiya bəyannaməsidir və onun ətraf funksiyası və ya skripti yerinə yetirildikdən sonra ( qaldırmaq səbəbindən) müəyyən edilir.

Məsələn, ifadə funksiyası:

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

Bu, funksiya bəyannamələrindən istifadə edərək funksiyaları şərti olaraq təyin edə bilməyiniz deməkdir:

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

Yuxarıda həqiqətən test dəyərindən asılı olmayaraq functionThree müəyyənləşdirir - use strict hərəkət etmədiyi halda, sadəcə səhv olur.

4669
03 дек. Greg 03 dek verilmiş cavab 2008-12-03 14:37 '08 at 2:37 pm 2008-12-03 14:37

İlk olaraq Greg'i düzeltmek istiyorum: function abc(){} da məhduddur - adı abc bu abc tapıldığı sahədə müəyyənləşdirilir. Məsələn:

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

İkincisi, hər iki üslubu birləşdirə bilərsiniz:

 var xyz = function abc(){}; 

xyz adi olaraq müəyyən ediləcək, abc - bütün brauzerlərdə qeyri-müəyyəndir, lakin Internet Explorer - onun tərifinə etibar etmir. Lakin bədəninin içində müəyyən olunacaq:

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

Bütün brauzerlərdə yalançı istifadə etmək istəyirsinizsə, bu növü reklamdan istifadə edin:

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

Bu halda, həm xyz , həm də abc eyni obyektin takma adlarıdır:

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

Birləşdirilmiş üslubdan istifadə etmək üçün cəlbedici səbəblərdən biri funksiya obyektləri üçün "ad" atributudur ( Internet Explorer tərəfindən dəstəklənmir ). Əsasən, bir funksiyanı tanımladığınızda

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

adı avtomatik olaraq təyin olunur. Ancaq bunu təyin etdiyiniz zaman

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

adı boşdur - anonim bir funksiya yaratdıq və bir sıra dəyişikliyə təyin etdik.

Birləşdirilmiş üslubdan istifadə etmək üçün başqa bir yaxşı səbəb xarici istifadəçilər üçün uzun bir qeyri-ziddiyyətli ad vermək üçün qısa bir daxili adı istifadə etməkdir:

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

Yuxarıdakı nümunədə biz xarici adla eyni ola bilərik, lakin çox çətin olacaq (və daha yavaş).

(Özünüzə müraciət etmək üçün başqa yol da ardıcıl uzun və sabit rejimdə dəstəklənməyən arguments.callee istifadə etməkdir.)

Down, JavaScript hər iki ifadəni fərqli şəkildə ələ alır. Bu funksiya bəyannaməsidir:

border=0
 function abc(){} 

abc burada cari sahədə hər yerdə müəyyən edilir:

 // We can call it here abc(); // Works // Yet, it is defined down there. function abc(){} // We can call it again abc(); // Works 

Bundan əlavə, o, return istifadə edərək yüksəldi:

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

Bu bir funksiya ifadəsidir:

 var xyz = function(){}; 

xyz təyinatından buradan müəyyən edilir:

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

Funksiya bəyannaməsi və funksiya ifadəsi Greq tərəfindən göstərilən bir fərqin əsl səbəbidir.

Fun fakt:

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

Şəxsən mən "funksiya ifadəsi" bəyannaməsini üstün tuturam, çünki bu şəkildə görünürlüğümü idarə edə bilərəm. Bir növ funksiyanı təyin edərkən

 var abc = function(){}; 

Mən funksiyanı yerli olaraq müəyyən etdiyini bilirəm. Bir növ funksiyanı təyin edərkən

 abc = function(){}; 

Mən bilirəm ki, mən bunu regionda zəncirində heç bir yerə abc tanımlamadığımı bildirərək, onu qlobal səviyyədə müəyyənləşdirdim. Bu definition tərzi, eval() içində istifadə eval() sabitdir. Tərif olsa da

 function abc(){}; 

kontekstdən asılıdır və xüsusilə eval() , müəyyənləşdirildikdə merak edə bilərsiniz - Cavab: Bu brauzerdən asılıdır.

1846
03 дек. Cavab Eugene Lazutkin 03 dekabrda verilir. 2008-12-03 20:43 '08 at 20:43 pm 2008-12-03 20:43

Burada funksiyaları yaradan standart formaların xülasəsi: (Başqa bir sual üçün başlanğıcda, lakin suallara keçiddən sonra uyğunlaşdırılmışdır).

Şərtlər:

Tez siyahısı:

  • Function bəyanatı

  • "Anonim" function İfadə (bu baxımdan bəzən adları ilə funksiyaları yaradır)

  • İfadə function

  • Access Function Initializer (ES5 +)

  • Arrow funksiyası ifadəsi (ES2015 +) (anonim iş ifadələri kimi, açıq bir ad içermir və funksiyaları adları ilə yarada)

  • Nəzarət başlanğıcında metod deklarasiyası (ES2015 +)

  • class konstruktor və metod bəyanatları (ES2015 +)

Function bəyanatı

Birinci forma aşağıdakı kimi görünən bir funksiya bəyannaməsidir:

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

Bir funksiya bəyannaməsi bir reklamdır; bu bir ifadə və ifadə deyil. Buna görə də onu təqib etmirsiniz ; (baxmayaraq ki, zərərsizdir).

İcra etmə, hər hansı bir addım kodunu icra etmədən əvvəl göründüyü kontekstə daxil olduqda, bir funksiya bəyannaməsi işlənir. Yaratdığı funksiyaya öz adı (yuxarıda göstərilən nümunədə) təyin edilir və bu ad bildirişin göründüyü əraziyə yerləşdirilir.

Eyni kontekstdə hər hansı bir addım kodundan əvvəl işlənildiyi üçün belə bir şey edə bilərsiniz:

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

ES2015-dən əvvəl, spesifikasiya bir idarəetmə strukturunun içərisində bir funksiya bəyannaməsi qoysaydı, JavaScript mühərrikinin nə etməsi lazım olduğunu, məsələn, switch vermək, və s.

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

Və addım-addım kodunu işə salmadan əvvəl işləndikləri üçün idarəetmə strukturunda olduqda nə edəcəyini bilmək çətindir.

ES2015-dən əvvəl göstərilməməsinə baxmayaraq, bloklardakı funksiya bəyannamələrini dəstəkləmək üçün etibarlı bir uzantı idi. Təəssüf ki (və qaçılmaz olaraq) fərqli mühərriklər fərqli şeylər etdi.

ES2015 ilə başlayaraq, spesifikasiya nə edəcəyini söyləyir. Əslində, bu üç ayrı fəaliyyət göstərir:

  1. Pulsuz rejimdə veb brauzerində olmasa, JavaScript mühərriki bir şey etməlidir.
  2. Bir web browserda pulsuz rejimdə JavaScript mühərriki başqa bir şey etməlidir.
  3. Əgər ciddi rejimdə (brauzer və ya deyil) JavaScript mühərriki daha bir şey etməlidir.

Pulsuz rejimin qaydaları çətin, lakin məhdud rejimdə bloklardakı funksiya bəyannamələri sadədir: onlar bloka yerli (onlar ES2015-də yeni olan blok sahəsi) və bloka qədər gedəcəklər. Beləliklə:

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

İfadə "anonim" function

İkinci ümumi forma anonim funksiya ifadəsi adlanır:

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

Bütün ifadələr kimi, addım-addım kodu yerinə yetirməklə hesablanır.

ES5-də yaradılmış funksiya heç bir adı yoxdur (anonimdir). ES2015-də bir funksiyaya kontekstdən kənarlaşdırmaq mümkün olduğunda bir ad verilir. Yuxarıdakı nümunədə adı y olacaq. Bu kimi bir funksiya funksiya başlanğıcının dəyəri olduqda olur. (Bu baş verdikdə və qaydalar haqqında daha ətraflı məlumat üçün, SetFunctionName -i müəyyən edin - hər yerdə görünür.)

İfadə function

Üçüncü forma adlandırılmış bir funksiyası olan bir ifadədir ("NFE"):

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

Yaratdığı funksiya öz adına (bu halda, w ) malikdir. Bütün ifadələr kimi, bu, addım-addımlı kodu yerinə yetirməklə əldə edildikdə qiymətləndirilir. Funksiya adı ifadəin göründüyü əraziyə əlavə edilmir; adı funksiyanın özü daxilindədir:

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

Xatırladaq ki, NFE-lər tez-tez JavaScript proqramları üçün səhvlərin qaynağıdır. Məsələn, IE8 və əvvəlki versiyalar NFE'yi tamamilə yanlış idarə edir, zamanında iki fərqli nöqtədə iki fərqli funksiya yaradır. Safari'nin erkən versiyaları da problemlər yaradıb. Yaxşı xəbərdir ki, brauzerlərin mövcud versiyalarında (IE9 və daha yüksək olan, mövcud Safari) bu problemlər artıq mövcud deyildir. (Lakin təəssüf ki, bu yazı zamanı IE8 hələ də geniş yayılmışdır və bu səbəbdən internetin kodu olan NFE-nin istifadə edilməsi hələ problemlidir.)

Access Function Initializer (ES5 +)

Bəzən funksiyalar nəzərəçarpan dərəcədə nüfuz edə bilər; nə daxil funksiyaları haqqında. Burada bir nümunə:

 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" 

Xahiş edirəm ki, funksiyanı istifadə edərkən istifadə etmədi () ! Çünki bir əmlak üçün bir giriş funksiyasıdır. Biz almaq və əmlakı adi şəkildə qururuq, lakin səhnələrin arxasında bir funksiya çağırılır.

Ayrıca Object.defineProperty , Object.defineProperties və daha az tanınan ikinci Object.create arqumenti istifadə edərək, giriş funksiyalarını yarada bilərsiniz.

Ok funksiyası ifadəsi (ES2015 +)

ES2015 bizə ox funksiyasını gətirir. Burada bir nümunə var:

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

Xəritədə map() zəngdə n => n * 2 nəyin gizli olduğuna baxın? Bu bir funksiyadır.

Okların funksiyaları haqqında bir neçə şey:

  1. Bunların özü yoxdur. Bunun əvəzinə onlar müəyyənləşdirildikləri kontekstə yaxınlaşırlar. (Onlar da arguments yaxındırlar və lazım olduğu yerlərdə superdur). Deməli, this da bunların içindədir, onlar yaradılan və dəyişdirilə bilməz.

  2. Yuxarıda qeyd etdiyimiz kimi, siz sözün function istifadə etmirsiniz; Bunun əvəzinə => istifadə edin.

Məsələn n => n * 2 yuxarıdakı formalardan biridir. Bir funksiyanı keçmək üçün bir neçə dəlil varsa, parens istifadə edirsiniz:

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

(Unutmayın, Array#map ilk argument kimi qeydini, ikinci isə endeksini verir.)

Hər iki halda da funksiya orqanı yalnız bir ifadədir; funksiyanın qaytarılması dəyəri avtomatik olaraq bu ifadəin nəticəsidir (açıq return istifadə etməyin).

Yalnız bir ifadədən daha çox istifadə etsəniz, hər zaman olduğu kimi, {} və açıq return (dəyər qaytarmaq lazımdırsa) istifadə edin:

 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 bir versiya bir ifadə orqanı və ya qısa bir bədən ilə ox funksiyası deyilir. (Həmçinin: oxun qısa funksiyası.) Bədəni müəyyən edən {... } funksiyası funksiyanın orqanı ilə oxun funksiyasıdır. (Həmçinin: fiil ox funksiyası.)

Nəzarət başlanğıcında metod deklarasiyası (ES2015 +)

ES2015, metodun tərifi adlı bir funksiyaya aid olan daha qısa mülkiyyət bəyannaməsi formasına imkan verir; belə görünür:

 var o = { foo() { } }; 

ES5 və əvvəlki versiyalarında demək olar ki, bərabərdir:

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

Fərq (cədvəl istisna olmaqla) metod super istifadə edə bilər, lakin funksiya bilməz. Beləliklə, məsələn, bir metodun sintaksisini istifadə edən (say) valueOf (müəyyən) bir obyektin varsa, super.valueOf() istifadə super.valueOf() , Object.prototype.valueOf olan Object.prototype.valueOf dəyərini (bir şey bununla başqa bir şey var), Object.prototype.valueOf.call(this) Versiyası yerinə Object.prototype.valueOf.call(this) etmək lazımdır.

Bu da metodun müəyyənləşdirildiyi obyektə aiddir, buna görə də bu obyekt müvəqqəti olduqda (məsələn, Object obyektinə keçmək üçün orijinal obyektlərdən biri kimi), metodun sintaksisi obyektin başqa bir şey zibil toplayıcısı tərəfindən toplana bilər (JavaScript mühərriki bu vəziyyəti aşkar etmirsə və onu idarə etmirsə, metodlardan heç biri super istifadə etməsə).

class konstruktor və metod bəyanatları (ES2015 +)

ES2015 bizi elan edilmiş konstruktorlar və üsullar daxil olmaqla, class sözdizimi ilə təmin edir:

 class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getFullName() { return this.firstName + " " + this.lastName; } } 

getFullName iki funksiya bəyannaməsi var: biri Person adını verən konstruktor və getFullName üçün, getFullName təyin olunmuş funksiya olan Person.prototype .

574
04 марта '14 в 16:35 2014-03-04 16:35 Cavab TJ Crowder tərəfindən 04 Mart 'da 16:35' də verilir 2014-03-04 16:35

Qlobal kontekstdə danışarkən, həm var , həm də FunctionDeclaration ifadələri sonunda qlobal obyekt üçün silinməz bir xüsusiyyət yaradır, lakin hər ikisinin dəyəri də yaza bilər.

İki yol arasındakı incə fərq, dəyişkən Instantiation prosesinin başlandığında (faktiki kodun icrasından əvvəl), var ilə bəyan edilən bütün identifikatorların müəyyənləşdirilməyəcəyi ilə başlayacaq və FunctionDeclaration tərəfindən istifadə edilənlər bundan sonra mövcud olacaq:

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

bar FunctionExpression tapşırığı yerinə yetirilmədən əvvəl aparılır.

FunctionDeclaration tərəfindən yaradılan qlobal əmlak, məsələn, bir dəyişənin dəyəri ilə eyni şəkildə heç bir problem olmadan yazıla bilər:

  function test () {} test = null; 

İki nümunəniz arasındakı başqa bir fərq, birinci funksiyanın adın olmadığını, lakin ikincisinin də diskussiya edərkən (məsələn, zəng yığınını yoxlamaq) həqiqətən faydalı ola biləcəyi var.

Sizin düzəliş edilən ilk foo = function() { alert('hello!'); }; haqqında ( foo = function() { alert('hello!'); }; ), Bu bildirilməmiş bir vəzifədir, mən həmişə açar sözü var istifadə məsləhətdir.

Bir var operator olmadan təyin edildikdə, istinad identifikatoru əhatə zəncirində tapılmadıqda, qlobal obyektin çıkarılabilir xüsusiyyətinə çevriləcəkdir.

Bundan əlavə, bildirilməmiş vəzifələr ECMAScript 5-də Qətilik rejimində ReferenceError təhvil verir.

A oxumalıdır:

Qeyd : Bu cavab başqa bir sualdan birləşdirildi ki, burada əsas şübhə və OP-dən yanlış anlaşılma FunctionDeclaration ilə işlədilən şəxslər FunctionDeclaration ilə FunctionDeclaration bilmədi, bu isə bu deyil.

137
08 авг. Cavab CMS 08 aug tərəfindən verilir . 2010-08-08 22:32 '10 at 10:32 2010-08-08 22:32

Burada qoyduğunuz iki kod snippetası demək olar ki, bütün məqsədlər üçün eyni davranır.

Lakin, davranış fərqi ilk var functionOne = function() {} ilə ( var functionOne = function() {} ) bu funksiyanı yalnız kodda bu nöqtədən sonra çağırmaq olar.

İkinci variantda ( function functionTwo() ) function functionTwo() elan olunduğu yerdə yuxarıda göstərilən kod üçün mövcuddur.

Bu, ilk variantda işlədilən zaman foo dəyişəninə funksiyanın verilməsi ilə bağlıdır. İkinci funksiyada, bu identifikator təhlil zamanı foo təyin edilir.

Əlavə texniki məlumat

JavaScript funksiyalarını təyin etmək üçün üç yol var.

  • İlk snippetinizdə funksiya ifadəsi göstərilir. Bu, bir funksiya yaratmaq üçün "funksiya" operatorunun istifadəsi ilə bağlıdır - bu operatorun nəticəsi dəyişən və ya obyektdə saxlana bilər. Funksiya ifadəsi çox güclüdür. Bir funksiya ifadəsi tez-tez "anonim funksiya" adlanır, çünki bir adı olmalı,
  • İkinci nümunə bir funksiya bəyannaməsidir. . Bir funksiya yaratmaq üçün "funksiya" operatorunu istifadə edin. Bu funksiya ayrıştırma zamanı təmin edilir və bu sahədə hər hansı bir yerə çağırılmalıdır. Daha sonra dəyişən və ya obyektdə saxlaya bilərsiniz.
  • Bir funksiyanı müəyyən etmək üçün üçüncü yol, orijinal mesajda göstərilməyən "Function ()" konstruktorudur. Bunu istifadə etmək tövsiyə edilmir, çünki öz problemləri olan eval() kimi işləyir.
115
20 апр. cümə axşamı cənab Tomsrutter tərəfindən cavab verildi 2010-04-20 07:54 '10 at 7:54 2010-04-20 07:54

Greg ən yaxşı şərhə cavab verir

 functionTwo(); function functionTwo() { } 

Niyə bugs? Biz həmişə ifadələrin yuxarıdan aşağıya (??)

Çünki:

Funksiya bəyannamələri və dəyişən bəyanatları həmişə JavaScript tercümanını istifadə edərək, bölgənin üstlərinə görünməz olaraq hərəkətə hoisted ( hoisted ). Funksional parametrlər və dil adları, əlbəttə ki, mövcuddur. ben albalı

Bu, belə bir kod deməkdir:

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

Bəyannamələrin verilməsi bir hissəsinin qaldırılmadığını nəzərə al. Yalnız ad qaldırılır.

Amma funksiya bəyannamələrində bütün funksiyanın cismi də qaldırılacaq:

 functionTwo(); --------------- function functionTwo() { | is actually | }; function functionTwo() { | interpreted |--> } | like | functionTwo(); --------------- 
96
09 авг. cavab simple_human 09 aug verilir . 2014-08-09 05:45 '14 saat 05:45 'da 2014-08-09 05:45

Digər şərhçilər artıq yuxarıda sadalanan iki variant arasındakı semantik fərqləri qiymətləndirmişlər. Bir üslub fərqini qeyd etmək istərdim: yalnız "təyinat" bir dəyişikliyi başqa bir obyektin mülkiyyətini qura bilər.

Mən tez-tez bu nümunə ilə JavaScript modulları yaradıram:

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

Bu şablondan istifadə edərək, özəl funksiyalarınız reklamı istifadə edərkən, ictimai funksiyaları təyinatı istifadə edəcək.

(Diqqət onu qadağan edərkən tapşırıqdan sonra nöqtə nöqtəli veriyi ehtiva etməlidir).

87
03 марта '11 в 22:19 2011-03-03 22:19 Sean McMillan'a 03.03.11 tarixində 22:19 'də cavab verdi 2011-03-03 22:19

İkincisi üçün birinci metoddan istifadə etmək daha yaxşıdırsa, əvvəlki anlayışların funksiyalarını dayandırmaqdan çəkinmək lazımdır.

İlə

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

bu tərif myfunction hər hansı bir əvvəlki tərifi ləğv myfunction , çünki təhlil edilərkən icra ediləcəkdir.

Baxmayaraq

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

condition yerinə yetirildiyi zaman myfunction təyin etmək üçün düzgün iş myfunction .

73
29 марта '13 в 16:26 2013-03-29 16:26 Mbengue Assane tərəfindən 29 Mart'ta saat 16 : 26-da veriləcək cavab 2013-03-29 16:26

Əhəmiyyətli bir səbəb adınızın "kökü" kimi bir və bir dəyişənin əlavə edilməsidır ...

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

və ya

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

Ad boşluğu üçün bir çox üsul var. Bu, mövcud olan bir çox JavaScript modulu ilə daha vacibdir.

Həmçinin baxın. İsmarıcları javascriptdə necə elan etmək olar?

59
08 авг. Cavab Rob 08 aug tərəfindən verilir . 2010-08-08 22:44 '10 at 10:44 PM 2010-08-08 22:44

Kaldırıcı dəyişənlərin və funksiyaların bütün bəyannamələrini mövcud sahənin başlanğıcına keçirmək üçün bir JavaScript tərcüməçi hərəkətidir.

Ancaq yalnız faktiki bəyanatlar qaldırılır. tapşırıqlarını buraxırlar.

  • переменная/функция, объявленная внутри страницы, глобально доступна для доступа в любой точке этой страницы.
  • переменные/функции, объявленные внутри функции, имеют локальную область. означает, что они доступны/доступны внутри тела функции (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' }; 

Функция, назначенная переменной Пример:

 (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 интерпретируется как

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

Вы можете проверить декларацию функции, тест выражения в другом браузере, используя jsperf Test Runner


Классы функций конструктора ES5 : Объекты функций, созданные с помощью Function.prototype.bind

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

 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 представила функцию стрелки : выражение функции стрелки имеет более короткий синтаксис, они лучше всего подходят для функций не-метода, и они не могут использоваться как конструкторы.

ArrowFunction : ArrowParameters => ConciseBody .

 const fn = (item) => { return item  1 ? 'Odd' : 'Even'; }; console.log( fn(2) ); // Even console.log( fn(3) ); // Odd 
52
ответ дан Yash 25 янв. '16 в 17:46 2016-01-25 17:46

Я добавляю свой собственный ответ только потому, что все остальные полностью закрыли подъемную часть.

Я задавался вопросом, какой путь лучше уже давно, и благодаря http://jsperf.com теперь я знаю:)

2019

36
ответ дан Leon Gaban 01 мая '15 в 18:06 2015-05-01 18:06

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

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

В принципе, все объявления функций и объявления переменных поднимаются в начало функции, в которой происходит объявление (поэтому мы говорим, что JavaScript имеет область видимости).

  • Когда объявляется объявление функции, тело функции "следует" поэтому, когда тело функции оценивается, переменная немедленно быть привязанным к объекту функции.

  • Когда объявление переменной отображается, инициализация не следовать, но "оставлен". Переменная инициализируется undefined в начале тела функции и будет назначен значение в исходном месте в коде. (На самом деле ему присваивается значение в каждом месте, где происходит объявление переменной с тем же именем.)

Порядок подъема также важен: объявления функций имеют приоритет над объявлениями переменных с тем же именем, а последнее объявление функции имеет приоритет над предыдущими объявлениями с тем же именем.

Некоторые примеры...

 var foo = 1; function bar() { if (!foo) { var foo = 10 } return foo; } bar() // 10 

Переменная foo поднимается в начало функции, инициализируется до undefined , так что !foo равно true , поэтому foo присваивается 10 . foo вне области bar не играет никакой роли и нетронутой.

 function f() { return a; function a() {return 1}; var a = 4; function a() {return 2}} f()() // 2 function f() { return a; var a = 4; function a() {return 1}; function a() {return 2}} f()() // 2 

Объявления функций имеют приоритет над объявлениями переменных, а последнее объявление функции "прилипает".

 function f() { var a = 4; function a() {return 1}; function a() {return 2}; return a; } f() // 4 

В этом примере a инициализируется объектом функции, полученным в результате оценки объявления второй функции, а затем назначается 4 .

 var a = 1; function b() { a = 10; return; function a() {}} b(); a // 1 

Здесь объявляется объявление функции, объявление и инициализация переменной a . Затем этой переменной присваивается 10 . Другими словами: присваивание не присваивается внешней переменной a .

32
ответ дан eljenso 06 февр. '13 в 19:29 2013-02-06 19:29

Первый пример - объявление функции:

 function abc(){} 

Второй пример - это выражение функции:

 var abc = function() {}; 

Основное различие заключается в том, как они поднимаются (поднимаются и объявляются). В первом примере объявляется объявление всей функции. Во втором примере поднимается только var 'abc', его значение (функция) будет undefined, а сама функция остается в том положении, в котором она объявлена.

Проще говоря:

 //this will work abc(param); function abc(){} //this would fail abc(param); var abc = function() {} 

Чтобы узнать больше об этой теме, я настоятельно рекомендую вам это ссылка

30
ответ дан sla55er 05 июня '14 в 11:28 2014-06-05 11:28

С точки зрения стоимости обслуживания кода более предпочтительными являются названные функции:

  • Независимо от места, где они объявлены (но все же ограничены областью).
  • Более устойчив к ошибкам, таким как условная инициализация (вы все еще можете переопределить, если захотите).
  • Код становится более читаемым, выделяя локальные функции отдельно от функциональности области. Обычно в область действия сначала входят функции, а затем декларации локальных функций.
  • В отладчике вы явно увидите имя функции в стеке вызовов вместо функции "анонимный/оцененный".

Я подозреваю, что больше PROS для названных функций. И то, что указано как преимущество названных функций, является недостатком для анонимных.

Исторически анонимные функции появились из-за невозможности JavaScript как языка для перечисления членов с именованными функциями:

 { member:function() {  } } 
28
ответ дан Sasha Firsov 23 янв. '10 в 23:32 2010-01-23 23:32

Я использую переменный подход в своем коде по очень определенной причине, теория которого была рассмотрена абстрактным образом выше, но пример может помочь некоторым людям, как я, с ограниченным опытом JavaScript.

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

Некоторые брендинги требуют определенных функций, а некоторые нет. Иногда мне приходится добавлять новые функции для создания новых брендинговых вещей. Я рад изменить общий код, но я не хочу менять все 160 наборов файлов брендинга.

Используя синтаксис переменных, я могу объявить переменную (по существу, указатель функции) в общем коде и либо назначить тривиальную функцию заглушки, либо установить значение null.

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

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

24
ответ дан Herc 29 нояб. '12 в 14:28 2012-11-29 14:28

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

Для получения дополнительной информации об анонимных функциях и исчислении лямбда, Википедия - хорошее начало ( http://en.wikipedia.org/wiki/Anonymous_function ).

22
ответ дан Kafka 18 дек. '08 в 22:30 2008-12-18 22:30

Greg Answer достаточно хорош, но я все еще хотел бы добавить что-то к нему, что я узнал только сейчас, наблюдая видео Дугласа Крокфорда.

Функциональное выражение:

 var foo = function foo() {}; 

Оператор функции:

 function foo() {}; 

Оператор функции является просто сокращением для оператора var с function значением.

Итак,

 function foo() {}; 

расширяется до

 var foo = function foo() {}; 

Расширяется далее:

 var foo = undefined; foo = function foo() {}; 

И они оба подняты в верхней части кода.

2019

22
ответ дан Rohan 21 июля '15 в 10:45 2015-07-21 10:45

@EugeneLazutkin дает пример, где он называет назначенную функцию, чтобы иметь возможность использовать shortcut() как внутренняя ссылка на себя. John Resig дает еще один пример - копирование рекурсивной функции, назначенной другому объекту в Изучение расширенного Javascript . Хотя назначение функций свойствам здесь не является строго вопросом, я рекомендую активно пробовать учебник - запустите код, нажав кнопку в правом верхнем углу, и дважды щелкните по коду, чтобы изменить его по своему вкусу.

Примеры из учебника: рекурсивные вызовы в yell() :

Тесты выходят из строя, когда исходный объект ниндзя удален. (стр. 13)

 var ninja = { yell: function(n){ return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; } }; assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); var samurai = { yell: ninja.yell }; var ninja = null; try { samurai.yell(4); } catch(e){ assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); } 

Если вы назовете функцию, которая будет вызываться рекурсивно, тесты пройдут. (стр. 14)

 var ninja = { yell: function yell(n){ return n > 0 ? yell(n-1) + "a" : "hiy"; } }; assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); var samurai = { yell: ninja.yell }; var ninja = {}; assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." ); 
18
ответ дан Joel Purra 04 авг. '12 в 18:24 2012-08-04 18:24

Другое отличие, которое не упоминается в других ответах, заключается в том, что если вы используете анонимную функцию

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

и использовать это как конструктор, как в

 var one = new functionOne(); 

то one.constructor.name не будет определено. Function.name является нестандартным, но поддерживается браузерами Firefox, Chrome, других Webkit и IE 9 +.

İlə

 function functionTwo() { // Some code } two = new functionTwo(); 

можно получить имя конструктора в виде строки с two.constructor.name .

15
ответ дан Ingo Kegel 15 окт. '12 в 13:42 2012-10-15 13:42

Если вы будете использовать эти функции для создания объектов, вы получите:

 var objectOne = new functionOne(); console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function var objectTwo = new functionTwo(); console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function 
14
ответ дан Pawel Furmaniak 25 окт. '13 в 19:38 2013-10-25 19:38

Я перечисляю следующие различия:

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

    Взгляните на приведенную ниже функцию:

     function outerFunction() { function foo() { return 1; } return foo(); function foo() { return 2; } } alert(outerFunction()); // Displays 2 

    Это происходит потому, что во время выполнения оно выглядит так: -

     function foo() { // The first function declaration is moved to top return 1; } function foo() { // The second function declaration is moved to top return 2; } function outerFunction() { return foo(); } alert(outerFunction()); //So executing from top to bottom, //the last foo() returns 2 which gets displayed 

    Выражение функции, если оно не определено до его вызова, приведет к ошибке. Кроме того, здесь само определение функции не перемещается в верхнюю часть или не помещается в память, как в объявлениях функций. Но переменная, которой мы назначаем функцию, поднимается вверх, и ей присваивается undefined .

    Те же функции, что и функциональные выражения:

     function outerFunction() { var foo = function() { return 1; } return foo(); var foo = function() { return 2; } } alert(outerFunction()); // Displays 1 

    Это происходит потому, что во время выполнения он выглядит так:

     function outerFunction() { var foo = undefined; var foo = undefined; foo = function() { return 1; }; return foo (); foo = function() { // This function expression is not reachable return 2; }; } alert(outerFunction()); // Displays 1 
  • Нельзя записывать объявления функций в не-функциональных блоках, например , если , потому что они не будут доступны.

     if (test) { function x() { doSomething(); } } 
  • Именованное выражение функции, подобное приведенному ниже, может не работать в браузерах Internet Explorer до версии 9.

     var today = function today() {return new Date()} 
14
ответ дан varna 09 сент. '15 в 13:30 2015-09-09 13:30

Первый (функция doSomething (x)) должен быть частью нотации объекта.

Второй ( var doSomething = function(x){ alert(x);} ) просто создает анонимную функцию и присваивает ее переменной doSomething . Таким образом doSomething() вызовет функцию.

Возможно, вам захочется узнать, что такое объявление функции и выражение функции.

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

 function foo() { return 3; } 

ECMA 5 (13.0) определяет синтаксис как
Идентификатор функции (FormalParameterList opt ) {FunctionBody}

В приведенном выше состоянии имя функции видимо в пределах ее области действия и области ее родителя (иначе это было бы недостижимо).

И в выражении функции

Функциональное выражение определяет функцию как часть синтаксиса большего выражения (обычно назначение переменной). Функции, определенные выражениями функций, можно назвать или анонимными. Выражения функций не должны начинаться с "функции".

 // Anonymous function expression var a = function() { return 3; } // Named function expression var a = function foo() { return 3; } // Self-invoking function expression (function foo() { alert("hello!"); })(); 

ECMA 5 (13.0) определяет синтаксис как
Идентификатор функции opt (FormalParameterList opt ) {FunctionBody}

14
ответ дан NullPoiиteя 05 янв. '13 в 21:37 2013-01-05 21:37

В свете аргументов "названные функции отображаются в стеках" современные механизмы JavaScript на самом деле вполне способны представлять анонимные функции.

Начиная с этой записи, V8, SpiderMonkey, Chakra и Nitro всегда ссылаются на именованные функции по их именам. Они почти всегда ссылаются на анонимную функцию по ее идентификатору, если она есть.

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

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

 [].forEach(function iterator() {}); 

Но по большей части это не стоит подчеркивать.

Жгут проводов ( Fiddle )

 'use strict'; var a = function () { throw new Error(); }, b = function b() { throw new Error(); }, c = function d() { throw new Error(); }, e = { f: a, g: b, h: c, i: function () { throw new Error(); }, j: function j() { throw new Error(); }, k: function l() { throw new Error(); } }, m = (function () { return function () { throw new Error(); }; }()), n = (function () { return function n() { throw new Error(); }; }()), o = (function () { return function p() { throw new Error(); }; }()); console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) { return values.concat(e[key]); }, [])).concat([m, n, o]).reduce(function (logs, func) { try { func(); } catch (error) { return logs.concat('func.name: ' + func.name + '\n' + 'Trace:\n' + error.stack); // Need to manually log the error object in Nitro. } }, []).join('\n\n')); 

V8

 func.name: Trace: Error at a (http://localhost:8000/test.js:4:11) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: b Trace: Error at b (http://localhost:8000/test.js:7:15) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: d Trace: Error at d (http://localhost:8000/test.js:10:15) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: Trace: Error at a (http://localhost:8000/test.js:4:11) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: b Trace: Error at b (http://localhost:8000/test.js:7:15) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: d Trace: Error at d (http://localhost:8000/test.js:10:15) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: Trace: Error at ei (http://localhost:8000/test.js:17:19) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: j Trace: Error at j (http://localhost:8000/test.js:20:19) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: l Trace: Error at l (http://localhost:8000/test.js:23:19) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: Trace: Error at http://localhost:8000/test.js:28:19 at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: n Trace: Error at n (http://localhost:8000/test.js:33:19) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 func.name: p Trace: Error at p (http://localhost:8000/test.js:38:19) at http://localhost:8000/test.js:47:9 at Array.reduce (native) at http://localhost:8000/test.js:44:27 test.js:42 

SpiderMonkey

 func.name: Trace: a@http://localhost:8000/test.js:4:5 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: b Trace: b@http://localhost:8000/test.js:7:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: d Trace: d@http://localhost:8000/test.js:10:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: Trace: a@http://localhost:8000/test.js:4:5 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: b Trace: b@http://localhost:8000/test.js:7:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: d Trace: d@http://localhost:8000/test.js:10:9 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: Trace: ei@http://localhost:8000/test.js:17:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: j Trace: j@http://localhost:8000/test.js:20:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: l Trace: l@http://localhost:8000/test.js:23:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: Trace: m</<@http://localhost:8000/test.js:28:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: n Trace: n@http://localhost:8000/test.js:33:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 func.name: p Trace: p@http://localhost:8000/test.js:38:13 @http://localhost:8000/test.js:47:9 @http://localhost:8000/test.js:54:1 

Chakra

 func.name: undefined Trace: Error at a (http://localhost:8000/test.js:4:5) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at b (http://localhost:8000/test.js:7:9) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at d (http://localhost:8000/test.js:10:9) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at a (http://localhost:8000/test.js:4:5) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at b (http://localhost:8000/test.js:7:9) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at d (http://localhost:8000/test.js:10:9) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at ei (http://localhost:8000/test.js:17:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at j (http://localhost:8000/test.js:20:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at l (http://localhost:8000/test.js:23:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at Anonymous function (http://localhost:8000/test.js:28:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at n (http://localhost:8000/test.js:33:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) func.name: undefined Trace: Error at p (http://localhost:8000/test.js:38:13) at Anonymous function (http://localhost:8000/test.js:47:9) at Global code (http://localhost:8000/test.js:42:1) 

Нитро

 func.name: Trace: a@http://localhost:8000/test.js:4:22 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: b Trace: b@http://localhost:8000/test.js:7:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: d Trace: d@http://localhost:8000/test.js:10:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: a@http://localhost:8000/test.js:4:22 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: b Trace: b@http://localhost:8000/test.js:7:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: d Trace: d@http://localhost:8000/test.js:10:26 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: i@http://localhost:8000/test.js:17:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: j Trace: j@http://localhost:8000/test.js:20:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: l Trace: l@http://localhost:8000/test.js:23:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: Trace: http://localhost:8000/test.js:28:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: n Trace: n@http://localhost:8000/test.js:33:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 func.name: p Trace: p@http://localhost:8000/test.js:38:30 http://localhost:8000/test.js:47:13 reduce@[native code] global code@http://localhost:8000/test.js:44:33 
12
ответ дан Jackson 12 окт. '14 в 3:58 2014-10-12 03:58

Существует четыре заслуживающих внимания сравнения между двумя различными объявлениями функций, перечисленными ниже.

  1. Наличие (объем) функции

Следующее работает, потому что function add() находится в пределах ближайшего блока:

 try { console.log("Success: ", add(1, 1)); } catch(e) { console.log("ERROR: " + e); } var add=function add(a, b){ return a + b; } 

Следующее не работает, потому что add объявлен после того, как он используется.

 function foobar(a, b){} console.log(foobar.name); 

 var a = function(){}; var b = (function(){ return function(){} }); console.log(a.name); console.log(b.name); 

Если для функции не заданы переменные, то именем функции является пустая строка ( "" ).

 var a = function(){}; var b = a; var c = b; console.log(a.name); console.log(b.name); console.log(c.name); 
  1. Спектакль

В Google V8 и Firefox Spidermonkey может быть разница в несколько микросекундных JIST-компиляций, но в итоге результат будет точно таким же. Чтобы доказать это, давайте рассмотрим эффективность JSPerf в микробенчмарках, сравнив скорость двух пустых фрагментов кода. Тесты JSPerf находятся здесь . И тесты jsben.ch находятся здесь . Как видите, есть заметная разница, когда их не должно быть. Если вы действительно такой же фанат производительности, как я, то, возможно, вам стоит попытаться уменьшить количество переменных и функций в области и, в частности, устранить полиморфизм (например, использовать одну и ту же переменную для хранения двух разных типов).

  1. Изменчивость изменчивости

Когда вы используете ключевое слово var для объявления переменной, вы можете переназначить другое значение этой переменной следующим образом.

 (function(){ "use strict"; const foobar = function(){}; // initial value try { foobar = "Hello World!"; // new value console.log("[no error]"); } catch(error) { console.log("ERROR: " + error.message); } console.log(foobar, window.foobar); })(); 

Интересно, что если мы объявим переменную как function funcName(){} , то неизменность переменной будет такой же, как и объявление ее с помощью var .

 try { // typeof will simply return "undefined" if the variable does not exist if (typeof add !== "undefined") { add(1, 1); // just to prove it console.log("Not a block"); }else if(add===undefined){ // this throws an exception if add doesn't exist console.log('Behaves like var add=function(a,b){return a+b}'); } } catch(e) { console.log("Is a block"); } var add=function(a, b){return a + b} 
  • Нормальная function add(){}

  • Оператор (например, if , else , for while , try / catch / finally , switch , do / while , with )

  • Функция стрелки с function add()

ответ дан Jack Giffin 15 янв. '18 в 4:55 2018-01-15 04:55

В JavaScript существует два способа создания функций:

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

     function fn(){ console.log("Hello"); } fn(); 

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

    Что вы должны знать, так это то, что функции на самом деле являются объектами в JavaScript; внутри мы создали объект для функции выше и дали ему имя, называемое fn, или ссылка на объект хранится в fn. Функции - объекты в JavaScript; экземпляр функции на самом деле является экземпляром объекта.

  • Функциональное выражение:

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

    JavaScript имеет первоклассные функции, т.е. создает функцию и назначает ее переменной так же, как вы создаете строку или номер и присваиваете ее переменной. Здесь переменной fn присваивается функция. Причиной этого понятия являются функции - объекты в JavaScript; fn указывает на экземпляр объекта указанной выше функции. Мы инициализировали функцию и назначили ее переменной. Он не выполняет функцию и не назначает результат.

Ссылка: Синтаксис объявления функции JavaScript: var fn = function() {} vs function fn() {}

10
ответ дан Anoop Rai 14 авг. '16 в 12:13 2016-08-14 12:13

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

Первый случай - выражение функции, которое загружается только тогда, когда интерпретатор достигает этой строки кода. Поэтому, если вы сделаете это следующим образом, вы получите сообщение об ошибке, что functionOne не является функцией .

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

Причина в том, что в первой строке значение функции не назначено, и, следовательно, это undefined. Мы пытаемся назвать его функцией, и, следовательно, получаем ошибку.

Во второй строке мы назначаем функцию анонимной функции functionOne.

Второй случай - объявления функций, которые загружаются до выполнения любого кода. Поэтому, если вы делаете следующее, вы не получите никакой ошибки, поскольку объявление загружается до выполнения кода.

 functionOne(); function functionOne() { // Some code } 
8
ответ дан Nitin9791 28 дек. '16 в 23:18 2015-12-28 23:18

О производительности:

Новые версии V8 ввели несколько оптимизаций под капотом, а также SpiderMonkey .

Теперь между выражением и объявлением нет никакой разницы. Выражение функции теперь будет быстрее .

Chrome 62.0.3202 2019

ответ дан Panos Kal. 28 сент. '17 в 7:34 2017-09-28 07:34

Они довольно похожи с некоторыми небольшими отличиями, первая - это переменная, которая назначается анонимной функции (Объявление функции), а вторая - обычным способом создания функции в JavaScript (анонимная декларация функции), у обоих есть использование, минусы и профи:

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

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

Функция Expression определяет функцию как часть большего синтаксис выражений (обычно назначение переменной). функции определенные через функции Выражения могут быть названы или анонимными. функция Выражения не должны начинаться с "функции" (следовательно, круглые скобки вокруг примера самопривязывания ниже).

Назначить переменную функции, значит нет Подъем, так как мы знаем, что функции в JavaScript могут Hoist, означает, что они могут быть вызваны до того, как они будут объявлены, в то время как переменные должны быть объявлены до получения доступа к ним, поэтому в этом случае мы не можем получить доступ к функции до того, где она была заявлена, и это может быть способ, которым вы пишете свои функции, для функций, возвращающих другую функцию, такая декларация может иметь смысл, также в ECMA6 и выше вы можете назначить это arrow, которая может использоваться для вызова анонимных функций, также этот способ объявления - лучший способ создания функций конструктора в JavaScript.

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

 function functionTwo() { // Some code } 

Объявление функции определяет именованную функциональную переменную без требующих назначения переменных. Объявление функций происходит как автономные конструкции и не могут быть вложены в не-функциональные блоки. Полезно думать о них как о братьях и сестрах переменных объявлений. Подобно тому, как объявления переменных должны начинаться с "var", Function Объявления должны начинаться с "функции".

Это обычный способ вызова функции в JavaScript, эта функция может быть вызвана до того, как вы ее объявите, как и в JavaScript. Все функции Get Hoisted, но если вы используете "strict", это не будет поднять, как ожидалось, это хороший способ вызвать все нормальные функции, которые не являются большими в строках, и ни одна из них не является конструкторской функцией.

Кроме того, если вам нужна дополнительная информация о том, как работает подъем в JavaScript, перейдите по ссылке ниже:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

7
ответ дан Alireza 09 мая '17 в 16:56 2017-05-09 16:56

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

5
ответ дан Tao 24 июня '15 в 13:08 2015-06-24 13:08

new Function() может использоваться для передачи тела функции в строку. И, следовательно, это можно использовать для создания динамических функций. Также передайте script без выполнения script.

 var func = new Function("x", "y", "return x*y;"); function secondFunction(){ var result; result = func(10,20); console.log ( result ); } secondFunction() 
4
ответ дан SuperNova 10 мая '16 в 10:05 2016-05-10 10:05
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос