結束書

by William Countiss

威廉·Countiss

結束書 (Closing the Book on Closures)

JavaScript closures are an important, but notoriously confusing concept. There’s no escaping it — if you want to grow as a developer, you need to understand what closures are and how to use them.

JavaScript閉包是一個重要的概念,但眾所周知令人困惑。 沒有逃避之路-如果您想成長為一名開發人員,則需要了解什么是閉包以及如何使用它們。

Don’t let the fancy name scare you — once you play around with closures a bit you’ll realize that there really isn’t much to them.

不要讓這個奇特的名字嚇到您-一旦您對閉包進行一點操作,您就會意識到它們確實沒什么用。

Let’s start with something simple:

讓我們從簡單的事情開始:

1 function sayGreeting(greeting) {  2  3     return function(name) {  4  5         console.log(greeting + " " + name);  6     }  7  8 }

You’ll notice right away that our function, sayGreeting, returns another function. I can do this in JavaScript because functions are considered first-class, which means that they can be passed around just like other data types such as a number, string, or boolean. This can make for some interesting syntax:

您會立即注意到我們的函數sayGreeting返回了另一個函數。 我可以在JavaScript中進行此操作,因為函數被認為是一流的,這意味著它們可以像數字,字符串或布爾值之類的其他數據類型一樣傳遞。 這可以產生一些有趣的語法:

1 function sayGreeting (greeting) {  2  3     return function (name) {  4  5         console.log (greeting + " " + name);  6     }  7  8 }  9 sayGreeting("Hello")("William");

So what would you expect to see in the console when we run this code? Think about it for a moment and then take a look at the image below.

因此,當我們運行此代碼時,您希望在控制臺中看到什么? 考慮一下,然后看下面的圖片。

If you guessed “Hello William”, you’re right. Go ahead and give yourself a pat on the back. Now, let’s take a closer look into why.

如果您猜到“ Hello William”,那是對的。 繼續拍一下自己的背。 現在,讓我們仔細研究一下原因。

sayGreeting("Hello")("William");

Remember that sayGreeting returns a function. As we mentioned earlier, functions in JavaScript are first-class, and may be passed around like any other data structure. So when sayGreeting(“Hello”) is invoked for the first time it executes and returns an anonymous function. A returned function may also be invoked, and that is why you are seeing the second set of parentheses: sayGreeting(“Hello”)(“William”)

請記住,sayGreeting 返回一個函數。 如前所述,JavaScript中的函數是一流的,并且可以像其他任何數據結構一樣傳遞。 因此,當首次調用sayGreeting(“ Hello”)時,它將執行并返回一個匿名函數。 還可能調用返回的函數,這就是為什么您看到第二組括號的原因:sayGreeting(“ Hello”) (“ William”)

To make this a bit easier to follow let’s change the code a little by setting the first invocation to a variable:

為了使它更容易理解,我們將第一次調用設置為變量,以對代碼進行一些更改:

1 function sayGreeting (greeting) {  2  3     return function(name) {  4  5         console.log(greeting + " " + name);  6     }  7  8 }  9 10 var sayHello = sayGreeting("Hello"); 11 sayHello("William");

If you run this in your console you’ll get the same result as before. But how does sayHello(“William”) know about the value of the parameter greeting from the sayGreeting function? To understand this, we’ll need to go a little deeper.

如果在控制臺中運行此命令,則將獲得與以前相同的結果。 但是sayHello(“ William”)如何從sayGreeting函數知道有關參數greeting的值? 要理解這一點,我們需要更深入一些。

Whenever a function is invoked, memory is set aside for that function and its contents, which stick around even after the function has finished executing. We can visualize this by wrapping the sayHello variable with a console.dir()

每當調用一個函數時,都會為該函數及其內容留出內存,即使在函數執行完畢后,這些內存仍會保留。 我們可以通過用console.dir()包裝sayHello變量來可視化它

1 function sayGreeting(greeting) {  2  3     return function(name) {  4  5         console.log(greeting + " " + name);  6     }  7  8 }  9 10 var sayHello = sayGreeting("Hello"); 11 12 console.dir(sayHello); 13 sayHello("William");

You’ll see in the console that the variable sayHello is an anonymous function, and within its scope there is a Closure with a name:value pair,

您會在控制臺中看到變量sayHello是一個匿名函數,并且在其范圍內有一個帶name:value對的C 閉環

greeting: “Hello”

問候:“你好”

This should look familiar since “greeting” is the name of the parameter of the sayGreeting(greeting) { … } function on line 1, and “Hello” was the string that we passed into it when we first invoked the function on line 10. Memory was then set aside for these values and is available as an outer reference when we invoke the function on line 13.

這應該看起來很熟悉,因為“ greeting”是第1行的sayGreeting(greeting){…}函數的參數名稱,而“ Hello”是我們在第10行首次調用該函數時傳遞給它的字符串。然后為這些值預留了內存,當我們在第13行調用該函數時,它可用作外部引用

To help visualize this let’s write out the body of the sayHello function as it is executed on line 13.

為了使這一過程可視化,讓我們在第13行執行時寫出sayHello函數的主體。

1 function (name) {  2  3     console.log (greeting + " " + name);  4 }

The string “William” is passed in for the name parameter, then on line 3 console.log(greeting + “ “+ name) is executed.

為name參數傳入字符串“ William”,然后在第3行console.log( greeting +““ + name )”被執行。

It then looks for the values of greeting and name.

然后,它查找greetingname的值。

Our function finds a value for name: “William”. But it doesn’t have a value for greeting. So now it’s time to go fishing, and it looks to its outer reference (where it sits in terms of lexical scope) in an attempt to find a value for greeting.

我們的函數查找名稱的值:“ William”。 但這沒有問候的價值。 因此,現在該釣魚了,它查找其外部參考(在詞匯范圍方面),以期尋找問候的價值。

In other words, it remembers where it was explicitly written in the code, which is inside of the sayGreeting function.

換句話說,它會記住它在sayGreeting函數內部的代碼中顯式編寫的位置。

1 function sayGreeting(greeting) {  2  3     return function(name) {  4  5         console.log(greeting + ' ' + name);  6     }  7  8 }

When it finds the value of greeting in its outer reference, we refer to this as closing in on an outer variable, and when this happens you have closure.

當它在其外部引用中找到greeting的值時,我們將其稱為外部變量上封閉 ,并且當發生這種情況時,您將具有closures

That wasn’t so bad, was it?

那還不錯,不是嗎?

This is a very basic example, but even in complex applications, the rules remain the same. Whenever a function can’t find the value of something within itself, it will follow the scope chain all the way down (or up depending upon how you envision it) and search for that value to create the closure.

這是一個非常基本的示例,但是即使在復雜的應用程序中,規則也保持不變。 每當函數無法在其自身中找到某個值時,它將一直沿作用域鏈向下(或向上延伸,具體取決于您對它的設想),并搜索該值以創建閉包。

翻譯自: https://www.freecodecamp.org/news/closing-the-book-on-closures-50b095289bfa/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396355.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396355.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396355.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java激勵_激勵干個人java的不足之處

1.你需要精通面向對象分析與設計(OOA/OOD)、涉及模式(GOF,J2EEDP)以及綜合模式。你應該十分了解UML,尤其是class,object,interaction以及statediagrams。2.你需要學習JAVA語言的基礎知識以及它的核心類庫(collections,…

Bioconductor軟件安裝與升級

1 安裝工具Bioc的軟件包不能使用直接install.packages函數,它有自己的安裝工具,使用下面的代碼: source("https://bioconductor.org/biocLite.R")biocLite() 上面第二個語句將安裝Bioconductor一些基礎軟件包,包括BiocI…

Laravel Kernel引導流程分析

Laravel Kernel引導流程分析 代碼展示 protected function sendRequestThroughRouter($request) {# $this->app->instance(request, $request);# Facade::clearResolvedInstance(request);// 主要是這句代碼$this->bootstrap();# return (new Pipeline($this->app)…

Android RecyclerView (一) 使用完全解析

轉載請標明出處: http://blog.csdn.net/lmj623565791/article/details/45059587; 本文出自:【張鴻洋的博客】 概述 RecyclerView出現已經有一段時間了,相信大家肯定不陌生了,大家可以通過導入support-v7對其進行使用。 據官方的…

數據透視表日期怎么選范圍_透視范圍

數據透視表日期怎么選范圍by Tiffany White蒂芙尼懷特(Tiffany White) 透視范圍 (Putting Scope in Perspective) In JavaScript, lexical scope deals with where your variables are defined, and how they will be accessible — or not accessible — to the rest of your…

feign調用多個服務_Spring Cloud 快速入門系列之feign–微服務之間的調用

我們將一個大的應用拆成多個小的服務之后,緊接著的一個問題就是,原本都在一個項目里,方法我可以隨便調用,但是拆開后,原來的方法就沒法直接調用了,這時候要怎么辦?Spring Cloud提供了feign&…

Asix下日志包沖突

為什么80%的碼農都做不了架構師?>>> Class org.apache.commons.logging.impl.SLF4JLogFactory does not implement org.apache.commons.logging. 最近集成asix包的時候發生如下錯誤,原因是程序運行時logFactoryImple加載了JBOSS下面的sff4j包…

kubernetes中mysql亂碼_在kubernetes中部署tomcat與mysql集群-Go語言中文社區

在kubernetes中部署tomcat與mysql集群之前必須要有以下這些基礎:1. 已安裝、配置kubernetes2. 集群中有tomcat與mysql容器鏡像3. 有docker基礎具體步驟部署tomcat創建tomcat RC對象我們想要在kubernetes集群中配置tomcat服務器,首先要保證集群中的節點上…

c# 測試運行時間毫秒級

long currentMillis (DateTime.Now.Ticks - (new DateTime(1970, 1, 1, 0, 0, 0, 0)).Ticks) / 10000;/*代碼*/long currentMillis1 (DateTime.Now.Ticks - (new DateTime(1970, 1, 1, 0, 0, 0, 0)).Ticks) / 10000;MessageBox.Show((currentMillis1 - currentMillis).ToStri…

nodejs_NodeJS歷險記

nodejsby Elliott McNary埃利奧特麥克納里(Elliott McNary) NodeJS歷險記 (Adventures in NodeJS) I built an app a couple of weeks ago after going through FreeCodeCamp’s Front-End curriculum and wanted to write an update as I head into NodeJS-land. I was final…

pytdx 獲取板塊指數_能否增加一個通過股票代碼,板塊指數代碼獲得中文名稱的接口?...

T0002/hq_cache/shex.tnfT0002/hq_cache/szex.tnf這個解碼就是。/***************************************************股票代碼列表和股票名稱T0002/hq_cache/shex.tnfT0002/hq_cache/szex.tnf***************************************************/struct TdxSymbolMap {cha…

靈動標簽調用友情鏈接

1、文字形式[e:loop{select * from [!db.pre!]enewslink where checked1 and classid1 order by myorder,20,24,0}] <li><a href"<?$bqr[lurl]?>" title"<?$bqr[lname]?>" target"_blank"><?$bqr[lname]?>&…

4-----Scrapy框架中選擇器的用法

Scrapy提取數據有自己的一套機制&#xff0c;被稱作選擇器&#xff08;selectors&#xff09;,通過特定的Xpath或者CSS表達式來選擇HTML文件的某個部分Xpath是專門在XML文件中選擇節點的語言&#xff0c;也可以用在HTML上。CSS是一門將HTML文檔樣式化語言&#xff0c;選擇器由它…

【原】Jenkins持續集成環境搭建之創建java項目的job【centos6.5 java maven git 項目】...

一、構建一個maven項目在jenkins主頁上&#xff0c;左側&#xff0c;選擇“新建”&#xff0c;然后填寫項目名稱&#xff0c;選擇“構建一個maven項目”二、Git配置保存之后&#xff0c;進入詳細配置頁面&#xff1a;這里的源碼管理&#xff1a;選擇git&#xff0c;輸入代碼的g…

linux修改java內存大小_Linux 和 windows修改java虛擬機內存大小

1、Java內存區域劃分&#xff1a; 運行時的數據區:方法區和堆(各個線程共享的內存區域)&#xff0c;程序計數器、Java虛擬機棧和本地方法棧(線程私有的) 程序計數器&#xff1a;當前線程所執行字節碼的行號指示器&#xff0c;字節碼解釋器就是通過改變計算器的值來選取下一條需…

html制作彩虹_制作彩虹

html制作彩虹by Gil Fewster吉爾弗斯特(Gil Fewster) 制作彩虹 (Making rainbows) This is a story about curiosity. It’s also about what happens when you stick a needle into your eye. If you happen to be eating a handful of grapes right this moment, maybe come…

python3 set_python3.x 基礎三:set集合

| clear(...) 清空一個集合| Remove all elements from this set.>>>set1.clear()>>>set1set()| copy(...) 影子復制&#xff0c;指向同一個內存地址| Return a shallow copy of a set. |>>> list1[3, 2, 1, 1, 2, 3, 4, 5]>>>…

Linux內核分析作業第八周

進程的切換和系統的一般執行過程 一、進程調度的時機 中斷處理過程&#xff08;包括時鐘中斷、I/O中斷、系統調用和異常&#xff09;中&#xff0c;直接調用schedule()&#xff0c;或者返回用戶態時根據need_resched標記調用schedule()&#xff1b; 內核線程可以直接調用sched…

iOS--數據存儲NSUserDefaults

2019獨角獸企業重金招聘Python工程師標準>>> 今天去面試&#xff0c;被問道NSUserDefaults的存取并手寫出來&#xff0c;一時想不起來&#xff0c;回來之后看看之前的筆記&#xff0c;稍作一些整理 NSUserDefaults是一個單例&#xff0c;在整個程序中只有一個實例對…

巨人肩膀_如何站在巨人的肩膀上

巨人肩膀“If I have seen further than others, it is by standing on the shoulders of giants.” — Isaac Newton“如果我能比其他人看到更多&#xff0c;那就是站在巨人的肩膀上。” —艾薩克牛頓 In 1676, Isaac Newton spoke of the great thinkers who came before him…