javascript
javascript闭包_通过邮寄包裹解释JavaScript闭包
javascript閉包
by Kevin Kononenko
凱文·科諾年科(Kevin Kononenko)
通過(guò)郵寄包裹解釋JavaScript閉包 (JavaScript Closures Explained by Mailing a Package)
如果您以前寄過(guò)包裹或信件,那么您可以了解JavaScript中的閉包。 (If you have mailed a package or letter in the past, then you can understand closures in JavaScript.)
On your journey to becoming an intermediate or advanced JavaScript dev, you may have come across closures. After reading a technical resource on the subject… you also probably ran in the opposite direction.
在成為中級(jí)或高級(jí)JavaScript開(kāi)發(fā)人員的過(guò)程中,您可能會(huì)遇到閉包的情況。 閱讀有關(guān)該主題的技術(shù)資源之后,您可能也朝相反的方向奔跑。
Here is the awesome thing about closures: they allow you to write functions with an intermediate step that can capture data from your site at a specific moment in time. It’s like adding a ‘pause’ button to your function. You can run your function and save the value of a variable at that particular point in time. Then, when you want to resume the function at a later point and use values of variables that have changed within your app… you can do that with a closure, or a function within the original function.
這是關(guān)于閉包的很棒的事情 :它們?cè)试S您編寫(xiě)帶有中間步驟的函數(shù),該中間步驟可以在特定時(shí)間捕獲站點(diǎn)中的數(shù)據(jù)。 這就像在功能中添加“暫停”按鈕一樣。 您可以運(yùn)行函數(shù)并在該特定時(shí)間點(diǎn)保存變量的值。 然后,當(dāng)您想在以后恢復(fù)該功能并使用在您的應(yīng)用程序中已更改的變量的值時(shí)...您可以使用閉包或原始功能中的一個(gè)功能來(lái)實(shí)現(xiàn) 。
This gets easier, I promise.
我保證,這會(huì)變得更容易。
So, when the heck would you use a closure?
那么,什么時(shí)候使用閉包呢?
Let’s say you are building an interactive map of tourist landmarks in New York City using the Google Maps API. You have an array with a bunch of map markers that you want to add to the map- the Statue of Liberty, Empire State Building, Coney Island, you name it. You want to add all these markers to the map, but you also want to add a click event to each marker. When you click the marker, you want to show dynamic information about that marker, including live weather data.
假設(shè)您正在使用Google Maps API構(gòu)建紐約市旅游地標(biāo)的交互式地圖。 您有一個(gè)包含一堆要添加到地圖的地圖標(biāo)記的數(shù)組-自由女神像,帝國(guó)大廈,康尼島,您將其命名。 您想將所有這些標(biāo)記添加到地圖,但也想將click事件添加到每個(gè)標(biāo)記。 單擊標(biāo)記時(shí),您要顯示有關(guān)該標(biāo)記的動(dòng)態(tài)信息,包括實(shí)時(shí)天氣數(shù)據(jù)。
var touristPlaces= […];for(var i=0; i< touristPlaces.length; i++){ var marker= touristPlaces[i]; $(marker).click(function(){ showToolTip(i) });}Here’s the issue- if you write it like this, it will not work. The ‘for’ loop will finish before the callback in the click event can register the appropriate i value. You need to capture this intermediate point so you can call the function later with the appropriate i.
這是問(wèn)題所在-如果您這樣編寫(xiě), 它將無(wú)法正常工作 。 在單擊事件中的回調(diào)可以注冊(cè)適當(dāng)?shù)膇值之前,“ for”循環(huán)將完成。 您需要捕獲此中間點(diǎn),以便稍后可以使用適當(dāng)?shù)膇調(diào)用該函數(shù)。
What do you need to know first?
您首先需要了解什么?
The concept of callbacks (I wrote a guide on this too!)
回調(diào)的概念(我也為此寫(xiě)過(guò)指南 !)
If you are looking for a technical explanation of closures, the guide on MDN is probably the best.
如果您正在尋找有關(guān)閉包的技術(shù)說(shuō)明, 則有關(guān)MDN的指南可能是最好的。
關(guān)閉與郵寄包裹的過(guò)程相同。 (Closures have the same process as mailing a package.)
Let’s look at some basic code that uses a closure to mail a package.
讓我們看一些使用閉包郵寄包裹的基本代碼。
The addressPackage() function is a closure! It can be called at any time after the packBox function has been called. It also has access to the variables and arguments from the time when packBox() was originally called.
addressPackage()函數(shù)是一個(gè)閉包 ! 可以在調(diào)用packBox函數(shù)后隨時(shí)調(diào)用它。 從最初調(diào)用packBox()以來(lái),它還可以訪問(wèn)變量和參數(shù)。
Notice how the console.log output does not show until lines 14 and 15? This is extremely important. If you ran this code after line 11, you would simply see ‘Put jersey in box’. There would be no error, but the closure, addressPackage(), would not run at that point.
請(qǐng)注意console.log輸出如何直到第14和15行才顯示? 這是非常重要的。 如果您在第11行之后運(yùn)行此代碼,則只會(huì)看到“將球衣放入框中”。 不會(huì)有錯(cuò)誤,但是閉包addressPackage()不會(huì)在此時(shí)運(yùn)行。
When you are mailing a package, you would probably agree that your job is not done until the package is filled and the address is written. Likewise, the packBox() function waits until the closure has also been called. Let’s go through this line-by-line.
當(dāng)您郵寄包裹時(shí),您可能會(huì)同意在填滿包裹并寫(xiě)出地址之前不會(huì)完成您的工作。 同樣,packBox()函數(shù)將等待,直到還調(diào)用了閉包。 讓我們逐行進(jìn)行介紹。
Line 11: You create the variable brotherGift, which is an instance of the packBox() function. You are sending a jersey to your brother.
第11行:創(chuàng)建變量brotherGift,它是packBox()函數(shù)的一個(gè)實(shí)例 。 您正在向您的兄弟發(fā)送球衣。
Line 3: Your code logs a statement about the jersey.
第3行:您的代碼記錄了有關(guān)球衣的聲明。
Line 8: The packBox() function returns… another function? Huh?
第8行: packBox()函數(shù)返回…另一個(gè)函數(shù)? ??
Let’s stop here, and assume that line 13 has not run yet. Here is what is happening: The packBox() function will not return the “ready to send” line until you also call the addressPackage() function with an argument. Just like there are two steps to sending a package: first, filling it, and second, addressing it. Your package is worthless if it has no contents or it does not have an address! That being said, you do not necessarily need to address the package directly after you fill the contents. You can wait a few days before addressing it. You might need to go to your computer to look up the address. You might be waiting for your brother to officially change his address!
讓我們?cè)谶@里停止,并假設(shè)第13行尚未運(yùn)行。 這是發(fā)生的情況:在您還使用參數(shù)調(diào)用addressPackage()函數(shù)之前,packBox()函數(shù)將不會(huì)返回“準(zhǔn)備發(fā)送”行。 就像發(fā)送包裹有兩個(gè)步驟一樣:第一步,填充包裹,第二步,處理包裹。 如果您的包裹沒(méi)有物品或沒(méi)有地址,那將毫無(wú)價(jià)值! 話雖如此,填寫(xiě)內(nèi)容后,您不一定需要直接處理包裹。 您可以等待幾天,然后再解決。 您可能需要轉(zhuǎn)到計(jì)算機(jī)以查找地址。 您可能正在等待您的兄弟正式更改他的地址!
Regardless, if you do not address the package immediately, this does not mean that the package will somehow magically empty itself. The contents will still be there when you return to address it! So, any time we call brotherGift, the first argument, jersey, will still be available.
無(wú)論如何,如果您不立即處理該軟件包,這并不意味著該軟件包將以某種方式神奇地清空其自身。 返回地址時(shí)內(nèi)容仍然在那里! 因此,無(wú)論何時(shí)我們將其稱為brotherGift,第一個(gè)參數(shù)jersey仍然可用。
…Waiting…Waiting…Now let’s run line 13.
…正在等待…正在等待…現(xiàn)在運(yùn)行第13行。
Line 13: Alright, let’s finish off this instance! You are ready to add the address, so you call brotherGift and offer the address as an argument. Remember from line 11, brotherGift is an instance of packBox with the ‘jersey’ argument. So when you call it, you are offering another argument, which will then be sent to the closure: addressPackage();
第13行:好的,讓我們結(jié)束這個(gè)實(shí)例 ! 您已經(jīng)準(zhǔn)備好添加地址,因此可以調(diào)用brotherGift并提供該地址作為參數(shù)。 請(qǐng)記住,從第11行開(kāi)始,brotherGift是帶有'jersey'參數(shù)的packBox的實(shí)例 。 因此,當(dāng)您調(diào)用它時(shí),您將提供另一個(gè)參數(shù),然后將其發(fā)送到閉包:addressPackage();
Line 3: The console.log will show since we are now running the code from line 13.
第3行:由于我們現(xiàn)在正在運(yùn)行第13行的代碼,因此將顯示console.log。
Line 4: We now offer the second argument to addressPackage();
第4行:現(xiàn)在,我們?yōu)閍ddressPackage()提供第二個(gè)參數(shù);
Line 6: addressPackage logs a statement related to the address argument.
第6行: addressPackage記錄與address參數(shù)相關(guān)的語(yǔ)句。
Line 8: The return statement can fire for this instance.
第8行: return語(yǔ)句可以為此實(shí)例觸發(fā)。
Again, closures allow us to have this intermediate instance where one argument has been filled, but brotherGift is left unfulfilled until we add the second argument. If we wanted to do this in one line, we would write: packBox(‘jersey’)(‘123 Main Street, Anywhere USA 01234’);
再次,閉包允許我們擁有一個(gè)已填充一個(gè)參數(shù)的中間實(shí)例,但是在添加第二個(gè)參數(shù)之前,不執(zhí)行brotherGift。 如果要在一行中執(zhí)行此操作 ,則應(yīng)編寫(xiě):packBox('jersey')('123 Main Street,Anywhere USA 01234');
再舉一個(gè)例子 (One More Example)
Let’s say that you wanted to send a gift to each member of your family. You might pack each box before adding the addresses to each. This is what that looks like in code.
假設(shè)您想發(fā)送禮物給家人。 您可以在將每個(gè)地址添加到每個(gè)地址之前打包它們。 這就是代碼中的樣子。
Another magical feature of closures! Each instance is able to use the correct gift item with the correct address, even thought we run the function with 4 separate gift/address pairs. In a traditional function, there is no concept of memory. You would need to explicitly restate the original gifts in lines 6–15 if you wanted to use a traditional function.
關(guān)閉的另一個(gè)神奇功能! 每個(gè)實(shí)例都能夠使用具有正確地址的正確禮物項(xiàng)目,即使我們以4個(gè)單獨(dú)的禮物/地址對(duì)運(yùn)行該功能也是如此。 在傳統(tǒng)功能中,沒(méi)有內(nèi)存的概念。 如果要使用傳統(tǒng)功能,則需要在第6-15行中明確聲明原始禮物。
您將在哪里使用 (Where You Will Use This)
You will frequently encounter closures in Node.js. If you are just interested in the front-end, think back to our original example. If you want to write a function that considers user input at two separate stages of your app, you may want to consider a closure!
您將經(jīng)常在Node.js中遇到閉包。 如果您只是對(duì)前端感興趣,請(qǐng)回想一下我們最初的示例。 如果要編寫(xiě)一個(gè)在應(yīng)用程序的兩個(gè)單獨(dú)階段考慮用戶輸入的函數(shù),則可能需要考慮閉包!
Did you enjoy this guide? Or are you having trouble with another JavaScript topic? Give it a heart and let me know in the comments!
您喜歡本指南嗎? 還是您在處理另一個(gè)JavaScript主題時(shí)遇到麻煩? 放心,讓我在評(píng)論中知道!
Looking for other JavaScript concepts explained? Check out these past articles in the series.
尋找其他解釋過(guò)JavaScript概念嗎? 查看本系列中的這些過(guò)去的文章。
JavaScript Promises Explained By Gambling At A Casino
在賭場(chǎng)賭博解釋JavaScript承諾
Model-View-Controller (MVC) Explained Through Ordering Drinks At The Bar
通過(guò)在酒吧訂購(gòu)飲料來(lái)解釋模型視圖控制器(MVC)
JavaScript Callbacks Explained Using Minions
使用Minions解釋JavaScript回調(diào)
翻譯自: https://www.freecodecamp.org/news/javascript-closures-explained-by-mailing-a-package-4f23e9885039/
javascript閉包
總結(jié)
以上是生活随笔為你收集整理的javascript闭包_通过邮寄包裹解释JavaScript闭包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 梦到打死两条蛇好不好
- 下一篇: 引入 javascript_在您Java