Javascript funksiyaları əmri: niyə bu vacibdir?

Orijinal sual:

JSHint mənim javascript səhifəmdəki daha bir funksiyaya zəngdən daha çox funksiya çağırdığı zaman şikayət edir. Buna baxmayaraq, mənim səhifəm oyun üçün nəzərdə tutulub və bütün bunlar yüklənməyincə heç bir funksiya çağırılmayacaq. Beləliklə, əmr funksiyaları niyə kodumda göstərilir?

EDIT: Hesab edirəm ki, cavab tapdım.

http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hotting

İçəridə inadım. Bəli, bir gün sərf etməliyəm, altı min kod satırını yenidən sıralayıram. Javascript ilə öyrənmə curve heç də sərin deyil, lakin çox loooooong.

94
30 сент. Chris Tolworthy tərəfindən təyin edilən Sep 30 2011-09-30 13:45 '11 saat 13:45 'də 2011-09-30 13:45
@ 4 cavab

tl; dr Hər şey yüklənənədək bir şey demirsinizsə, yaxşı olmalısınız.


Değişiklik: bəzi ES6 ( const ) bildirişlərini əhatə edən bir baxış: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet

Bu qəribə davranış asılıdır

  1. Funksiyaları necə müəyyənləşdirirsiniz?
  2. Onlara zəng etdikdə.

Burada bəzi nümunələr var.

 bar(); //This won't throw an error function bar() {} foo(); //This will throw an error var foo = function() {} 
 bar(); function bar() { foo(); //This will throw an error } var foo = function() {} 
 bar(); function bar() { foo(); //This _won't_ throw an error } function foo() {} 
 function bar() { foo(); //no error } var foo = function() {} bar(); 

Bu, qaldırılan bir şeydir!

Funksiyaları müəyyənləşdirmək üçün iki yol var: Function declaration və funksiya ifadəsi. Fərqli və bir dəqiqə zəhmət çəkir, buna görə də bir az yanlış bir şey deyək: əgər function name() {} kimi function name() {} , bu bir elanvar name = function() {} yazdığınızda var name = function() {} (və ya geri dönmək üçün təyin edilmiş anonim funksiya belə şeylər), bir funksiyanın ifadəsidir .

Birincisi, dəyişənlərin necə idarə edildiyini görək:

 var foo = 42; //the interpreter turns it into this: var foo; foo = 42; 

İndi funksiya bəyannamələrinin necə işləndiyi:

 var foo = 42; function bar() {} //turns into var foo; //Insanity! It now at the top function bar() {} foo = 42; 

var operatorları " foo " nin yaradılması üçün çox üstünə atırlar, lakin hələlik bir dəyər vermirlər. Funksiya aşağıdakı kimi elan edilir və nəhayət, dəyəri foo təyin olunur.

Bu nədir?

 bar(); var foo = 42; function bar() {} //=> var foo; function bar() {} bar(); foo = 42; 

Yalnız reklam foo doğru hərəkət edir. Tapşırıq yalnız bütün liftların baş vermədiyindən bar çağırılandan sonra baş verir.

Və nəhayət, qısa:

 bar(); function bar() {} //turns to function bar() {} bar(); 

İndi funksional ifadələr necədir?

 var foo = function() {} foo(); //=> var foo; foo = function() {} foo(); 

Sıravi dəyişənlər kimi, ilk foo bölgənin ən yüksək nöqtəsində elan edilir, sonra isə bir dəyər verilir.

Niyə ikinci nümunə bir səhv səbəb olur baxaq.

 bar(); function bar() { foo(); } var foo = function() {} //=> var foo; function bar() { foo(); } bar(); foo = function() {} 

Daha əvvəl gördüyümüz kimi, yalnız foo yaradılması yaranır, tapşırıq "orijinal" (yüksək olmayan) kodda göründükdə baş verir. bar çağırıldığında, foo bir dəyər təyin olunur, belə ki foo === undefined . İndi funksional bədən bar , sanki undefined() edilmədikdə undefined() , bir səhv doğurur.

262
30 сент. Cavab Zirak 30 sep verilir . 2011-09-30 16:13 '11 at 16:13 2011-09-30 16:13

Əsas səbəb, yəqin ki, JSLint faylda yalnız bir keçid təşkil edir, buna görə belə funksiyanı tanımadığınızı bilmir.

Sintaksis təlimat funksiyalarını istifadə etsəniz

 function foo(){ ... } 

Əslində, bir funksiyanı elan etdiyiniz heç bir fərq yoxdur (həmişə bəyanat başında olduğu kimi davranır).

Digər tərəfdən, əgər funksiyanız müntəzəm dəyişən kimi təyin olunarsa

 var foo = function() { ... }; 
border=0

Siz başlamazdan əvvəl onu çağırmadığınızdan əmin olmalısınız (bu səhvlərin qaynağı ola bilər).


Kodun bir tonunu yenidən təşkil etmək çox çətin və öz içində bir səhv mənbəyi ola bilər. Əminəm ki, JSLint qlobal dəyişənlərin adını qeyd edilməmiş şeylərdən şikayət etməmək üçün əvvəlcədən təyin edə bilərsiniz.

Faylın başlanğıcı haqqında bir şərh göndərin.

  

Bunun üçün mətn qutusunu istifadə edə bilərsiniz. (Mən də bununla müdaxilə edə biləcəyiniz təqdirdə daxili jslint funksiyasının argümanlarına keçə biləcəyinizi düşünürəm.)

6
30 сент. cavab verildi hugomg 30 sep . 2011-09-30 16:14 '11 'də 16:14' də 2011-09-30 16:14 'da

Javascript yazmaq üçün zahiri qaydaları tıklayan çox sayda insan var. Qaydaların əksəriyyəti zibildir.

Kaldırma funksiyası javascript funksiyasıdır, çünki yaxşı bir fikirdir.

Daxili funksiyadan istifadə edildikdə, daxili işləmələrin funksiyası xarici funksiyanın başlanğıcına əlavə edilsə, yazı yazmaq üçün məqbul bir üslubdur, ancaq xarici funksiyanı nə üçün əldə etdiyinizi ətraflı şəkildə oxumaqla kifayətlənir.

Sizin codebase boyunca bir prinsipə riayət etməlisiniz və ya modul və ya funksiyasında ilk və ya sonuncu funksiyaları qoyursunuz. JSHint tutarlılıq üçün yaxşıdır, ancaq ehtiyaclarınıza uyğun olaraq .jshintrc'i tənzimləməlisiniz, digər insanların digər kodlaşdırma konsepsiyaları üçün mənbə kodunu düzəltməyin.

Vahiddə gördüyünüz bir kodlama tərzindən çəkinməyin, çünki heç bir üstünlük verməyəcək və yalnız təkrar refrakterləşmə:

 function bigProcess() { var step1,step2; step1(); step2(); step1 = function() {...}; step2 = function() {...}; } 

Bu, qarşısını almaq lazımdır. Yalnız dil öyrənmək və güclü istifadə edin.

3
18 апр. Henrik Vendelbo tərəfindən 18 apreldə cavab verildi 2015-04-18 17:10 '15 saat 17:10 'da

Bir funksiyanın bəyan edilməsi yalnız bir ifadə (tapşırıq) funksiyası kimi elan edilmir.

1
13 дек. cavab 13 dekabrda Abhay Srivastav tərəfindən verilir . 2017-12-13 08:46 '17 də 8:46 'də 2017-12-13 08:46' də

tags ilə bağlı digər suallar və ya bir sual