Paano gumagana ang javascript blockers?

Paano mo ipapaliwanag ang pagsasara ng JavaScript para sa isang taong may kaalaman sa mga konsepto kung saan sila binubuo (halimbawa, mga function, mga variable, atbp.), Ngunit hindi nauunawaan ang mga pagsasara mismo?

Nakita ko ang isang halimbawa ng pamamaraan na ibinigay sa Wikipedia, ngunit, sa kasamaang-palad, hindi ito nakatulong.

7654
21 сент. naka-set sa e-satis sa 21 sept. 2008-09-21 17:12 '08 at 5:12 pm 2008-09-21 17:12
@ 89 sagot
  • 1
  • 2
  • 3

Pagsara ng javascript para sa mga nagsisimula

Naipasa ni Morris noong Tue, 2006-02-21 10:19. Ang komunidad ay na-edit mula noon.

Ang pagsara ay hindi magic

Ipinapaliwanag ng pahinang ito ang pagsasara upang maunawaan ng programmer ang mga ito - gamit ang nagtatrabaho JavaScript code. Hindi ito para sa mga gurus o functional programmers.

Ang pagsasara ay hindi mahirap maunawaan sa sandaling ang pangunahing konsepto ay naitahi. Gayunpaman, hindi nila maaaring maunawaan sa pamamagitan ng pagbabasa ng mga paliwanag na panteorya o pang-akademiko batay!

Ang artikulong ito ay inilaan para sa mga programmer na may i>

tampok na unang-class ;  ay isang expression na maaaring sumangguni sa mga variable sa loob ng saklaw nito (kapag ito ay dati nang ipinahayag), itatalaga sa isang variable, ipinasa bi>

Pagsasara ng halimbawa

Ang sumusunod na code ay nagbabalik ng sanggunian sa pag-andar:

 function say667() { // Local variable that ends up within closure var num = 42; var say = function() { console.log(num); } num++; return say; } var sayNumber = say667(); sayNumber(); // logs 43 

Halimbawa 4

Ang lahat ng tatlong pandaigdigang function ay may isang karaniwang reference sa parehong malapit, dahil ang lahat ng mga ito ay ipinahayag sa isang solong tawag sa setupSomeGlobals() .

 function sayAlice() { var say = function() { console.log(alice); } // Local variable that ends up within closure var alice = 'Hello Alice'; return say; } sayAlice()();// logs "Hello Alice" 

Nakakalito: tandaan rin, say variable na variable ay nasa loob din ng pagsasara, at maaari itong sabihin sayAlice() anumang iba pang mga function na maaaring ideklara sa sayAlice() , o maaari itong makuha nang recursively sa loob ng isang panloob na function.

Halimbawa 6

Ito ay tunay na magic para sa lahat ng mga tao, kaya kai>

Kai>

 function newClosure(someNum, someRef) { // Local variables that end up within closure var num = someNum; var anArray = [1,2,3]; var ref = someRef; return function(x) { num += x; anArray.push(num); console.log('num: ' + num + '; anArray: ' + anArray.toString() + '; ref.someVar: ' + ref.someVar + ';'); } } obj = {someVar: 4}; fn1 = newClosure(4, obj); fn2 = newClosure(5, obj); fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4; fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4; obj.someVar++; fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5; fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5; 

Buod

Kung ang lahat ng bagay tila ganap na maliwanag, ito ay pinakamahusay na upang i-play sa mga halimbawa. Ang pagbabasa ng mga paliwanag ay mas mahirap kaysa sa pag-unawa ng mga halimbawa. Ang aking mga paliwanag para sa mga pagsasara at mga stack frame, atbp. Hindi tama ang mga ito - ang mga ito ay mga simpleng pag-unawa na dinisenyo upang makatulong na maunawaan. Matapos malutas ang pangunahing ideya, maaari mong makuha ang mga detalye sa ibang pagkakataon.

Mga punto ng pagtatapos:

  • Tuwing gumamit ka ng function loob ng isa pang function, ang pagsasara ay ginagamit.
  • Sa tuwing ginagamit mo ang eval() loob ng isang function, ang isang malapit ay ginagamit. Ang tekstong eval mo ay maaaring sumangguni sa mga lokal na variable ng isang function, at sa eval maaari kang lumikha ng mga bagong lokal na variable na may eval('var foo = …')
  • Kapag gumamit ka ng new Function(…) ( function constructor ) sa loob ng isang function, hindi ito gumawa ng isang malapit. (Ang bagong function ay hindi maaaring sumangguni sa mga lokal na variable ng panlabas na function.)
  • Ang pagtatapos sa JavaScript ay tulad ng pagpapanatili ng isang kopya ng lahat ng mga lokal na variable, tulad ng kapag lumabas ka ng isang function.
  • Marahil ay pinakamahusay na mag-isip na ang pagsasara ay laging nalikha bi>
  • Ang isang bagong hanay ng mga lokal na variable ay naka-save sa bawat oras na ang isang function ay tinatawag na may isang pagsasara (ibinigay na ang function ay naglalaman ng isang function na deklarasyon sa loob nito, o ang reference sa panloob na function ay alinman ibinalik o ang panlabas na reference ay naka-imbak para sa mga ito sa i>
  • Maaaring tumingin ang dalawang mga pag-andar na kung mayroon si>
  • Kung sinusubukan mong gumawa ng anumang mga pagbabago sa dynamic source code (halimbawa: myFunction = Function(myFunction.toString().replace(/Hello/,'Hola')); ), hindi ito gagana kung ang myFunction ay isang pagsasara (siyempre, hindi mo na isipin ang pagpapalit ng mga linya ng pinagmulan sa runtime, ngunit ...).
  • Maaari kang makakuha ng mga deklarasyon ng function sa loob ng mga function declaration sa loob ng function na mdash, at maaari mong makuha ang pagsasara sa higit sa isang antas.
  • Sa palagay ko ang karaniwang pagsasara ay isang termino kapwa para sa isang function at para sa nakuha na mga variable. Pakitandaan na hindi ko ginagamit ang kahulugan na ito sa artikulong ito!
  • Pinaghihinalaan ko na ang mga pagsasara sa JavaScript ay naiiba mula sa mga karaniwang matatagpuan sa mga functional na wika.

mga koneksyon

salamat sa

Kung nalaman mo >


Ang orihinal na post ni Morris ay matatagpuan sa archive ng Internet .

6329
21 сент. ang sagot ay ibinigay ni Joel Anair 21 sep . 2008-09-21 17:18 '08 sa 17:18 2008-09-21 17:18

Sa tuwing makikita mo ang function na keyword sa isa pang function, ang panloob na function ay may access sa mga variable sa panlabas na function.

 function foo(x) { var tmp = 3; return function (y) { console.log(x + y + (++tmp)); // will also log 16 } } var bar = foo(2); // bar is now a closure. bar(10); 

Ang function sa itaas ay magsusulat din ng 16, dahil ang bar maaari pa ring sumangguni sa x at tmp , kahit na hindi na ito sa loob ng rehiyon.

Gayunpaman, dahil ang tmp nakabitin pa rin sa paligid ng pagsasara ng loob na bar , ito rin ay nagdaragdag. Ito ay dagdagan tuwing tatawag ka ng bar .

Ang pinakasimpleng halimbawa ng pagsasara ay ang mga sumusunod:

border=0

 function foo(x) { var tmp = 3; return function (y) { console.log(x + y + tmp); x.memb = x.memb ? x.memb + 1 : 1; console.log(x.memb); } } var age = new Number(2); var bar = foo(age); // bar is now a closure referencing age. bar(10); 

Tulad ng inaasahan, ang bawat tawag sa bar(10) ay magkakaroon ng x.memb . Hindi mo maaaring asahan ang x sumangguni lamang sa parehong bagay bi>age ! Pagkatapos ng i>bar age.memb 2! Ang link na ito ay nagsisilbing batayan para sa paglabas ng memory sa mga bagay na HTML.

3825
21 сент. sumagot na ibinigay kay Ali sa 21 Septiyembre. 2008-09-21 18:16 '08 at 6:16 pm 2008-09-21 18:16

PAHAYAGAN: ang sagot na ito ay isinulat kapag ang tanong ay:

Tulad ng lumang Albert, sinabi niya: "Kung hindi mo maipaliwanag ito sa isang anim na taong gu>

Maaari bang isipin ng isa na ako ay 6, at strangely interesado sa isyung ito?

Ako ay sigurado na ako ay isa sa mga taong nagsisikap na kunin ang paunang tanong sa literal. Simula noon, ang tanong na ito ay binago nang maraming beses, kaya ang aking sagot ay maaaring mukhang hindi kapani-paniwa>


Ako ay isang malaking tagahanga ng mga analogies at metaphors sa pagpapaliwanag ng mga kumplikadong mga konsepto, kaya hayaan mo akong subukan ang aking kamay sa kasaysayan.

Isang beses sa isang panahon:

Nagkaroon ng prinsesa ...

 function princess() { 

Siya ay nanirahan sa isang kahanga-hangang mundo na puno ng pakikipagsapalaran. Nakilala niya ang kanyang prince Charles, sumakay sa paligid ng kanyang mundo sa isang kabayong may sungay, nakipaglaban sa mga dragons, nakilala sa pakikipag-usap hayop at maraming iba pang mga kamangha-manghang bagay.

  var adventures = []; function princeCharming() {  } var unicorn = {  }, dragons = [  ], squirrel = "Hello!";  

Ngunit palaging kinai>

  return { 

At madalas niyang sinabi sa kanila ang tungkol sa kanyang huling kamangha-manghang pakikipagsapalaran bi>

  story: function() { return adventures[adventures.length - 1]; } }; } 

Ngunit ang lahat na nakita nila ay isang maliit na batang babae ...

 var littleGirl = princess(); 

... nagsasabi ng mga kuwento tungkol sa magic at pantasya.

 littleGirl.story(); 

At habang alam ng mga matatanda ang tungkol sa mga tunay na prinsesa, hindi sila kailanman naniwala sa mga unicorn o dragons, dahil hindi nila nakita ang mga ito. Sinabi ng mga matatanda na umiiral lamang sila sa loob ng imahinasyon ng isang batang babae.

Ngunit alam natin ang tunay na katotohanan; na ang isang maliit na batang babae na may isang prinsesa sa loob ...

... talaga isang prinsesa na may isang maliit na batang babae sa loob.

2273
24 июня '11 в 21:49 2011-06-24 21:49 ang sagot ay ibinigay ni Jacob Swartwood noong Hunyo 24 '11 sa 21:49 2011-06-24 21:49

Ang seryosong pagsasagawa ng katanungang ito, kai>

Sa pag- unlad ng pagkabata: 5 hanggang 7 taon na ito ay sinabi:

Ang iyong anak ay maaaring sumunod sa dalawang hakbang na direksyon. Halimbawa, kung sasabihin mo sa iyong anak: "Pumunta ka sa kusina at kumuha ng bag ng basura," maaalala nila ang direksyon na ito.

Maaari naming gamitin ang halimbawang ito upang ipaliwanag ang mga pagsara tulad ng sumusunod:

Ang isang kusina ay isang malapit na kung saan mayroong isang lokal na variable na tinatawag na trashBags . Sa loob ng kusina mayroong isang function na getTrashBag na tumatanggap ng isang basurang bag at getTrashBag ito.

Maaari naming i-encode ito sa javascript tulad ng sumusunod:

696
02 сент. ang sagot ay ibinigay dlaliberte 02 sep . 2011-09-02 18:23 '11 sa 18:23 2011-09-02 18:23

Dayami tao

Kai>

Malinaw na solusyon

 <button id="button">Click Me!</button> 

Ito ay gagana ngayon, ngunit ito ay sumasalakay sa panlabas na lugar, nagdaragdag ng isang variable na ang tanging layunin ay upang masubaybayan ang account. В некоторых ситуациях это было бы предпочтительнее, так как вашему внешнему приложению может потребоваться доступ к этой информации. Но в этом случае мы меняем только каждый третий клик, поэтому рекомендуется включать эту функциональность внутри обработчика событий .

Рассмотрим этот вариант

 <button id="button">Click Me!</button>