導航:首頁 > 程序命令 > 程序員閉包講解

程序員閉包講解

發布時間:2022-07-13 22:12:32

Ⅰ js閉包怎麼寫

varresult=[];
functionfoo(){
vari=0;
for(;i<3;i=i+1){
result[i]=function(){
alert(i)
}
}
};
foo();
result[0]();//3
result[1]();//3
result[2]();//3

這段代碼中,程序員希望foo函數中的變數i被內部循環的函數使用,並且能分別獲得他們的索引,而實際上,只能獲得該變數最後保留的值,也就是說.閉包中所記錄的自由變數,只是對這個變數的一個引用,而非變數的值,當這個變數被改變了,閉包里獲取到的變數值,也會被改變.


解決的方法之一,是讓內部函數在循環創建的時候立即執行,並且捕捉當前的索引值,然後記錄在自己的一個本地變數里.然後利用返回函數的方法,重寫內部函數,讓下一次調用的時候,返回本地變數的值,改進後的代碼:

varresult=[];
functionfoo(){
vari=0;
for(;i<3;i=i+1){
result[i]=(function(j){
returnfunction(){
alert(j);
};
})(i);
}
};
foo();
result[0]();//0
result[1]();//1
result[2]();//2

Ⅱ 程序員有哪些黑話暗語

所以你正在學習如何編寫代碼,超越默認的Hello World例子,並把你的技能提高到一個新的水平。恭喜!

如果你一步步地進行編碼,編碼並不難,但是如果你開始新鮮的話,很難說開發者的語言。

我們要求我們頂尖的開發者作者就一些最重要的術語和概念向新的編碼人員提供他們的忠告。這是前18名。

變數

變數是與相關聯的值在整個應用程序或程序的執行而改變命名標識符。一旦在程序中定義了一個變數,在需要時可以改變該值以適應代碼的流程。

常量

常數是與相關聯的值,該值不整個應用程序或程序的執行改變命名標識符。與在整個應用程序的執行過程中變化和變化的變數相比,常量是固定的,不能被改變。

數據類型

一個特定類型的數據項,由它可以接受的值定義,所涉及的編程語言和/或可以在其上執行的操作。常見的數據類型包括整數(簡單數字),浮點數(基於十進制的數字),布爾值(TRUE或FALSE)和字元串(字母,數字或段落等字母數字字元串)好多其它的。

數據結構

數據結構是用於組織和在最適合的目的數據將被用於的方式存儲數據的專用格式。編程中的常見數據結構包括數組,表格,記錄,樹等等。

對象

在面向對象的編程語言中,對象是指可以共同訪問和管理的相關變數,常量,函數(也稱為方法)和數據結構的組合。

范圍

范圍是指程序的一部分中的功能,方法和變數在同一程序的另一部分中的可見性。大多數語言共享兩個通用作用域概念:局部作用域(其中可見性僅限於父函數或方法)和全局作用域(其中可見性不受限制)。

偽代碼

就像粗糙的草稿在最後的小說之前,並允許對故事的更廣泛的細節進行雕刻一樣,偽代碼是在編寫和調試實際代碼之前用於概述程序的意圖和流程的編程語言的簡化速記。

條件語句

當代碼必須選擇繼續的方式時,條件處理這些決定。條件評估為TRUE或FALSE,只要條件的最終值保持單個TRUE或FALSE值,則可以將多個條件組合為單個條件。表達式的一些例子是:

my_variable <5 =「」>

(如果my_variable小於5,則最終值為TRUE)

my_var1> 30 && my_var2 == 4(如果my_var1大於30,且my_var 2也等於4,則最終值為TRUE)

表達式

一個表達式是由ofvariables,數字和操作的數學表達式,並解析到一個特定的值。

循環

一連串的指令不斷重復(循環),直到達到一定的條件。

模塊化代碼

模塊化代碼是將你的程序功能分離成獨立的模塊的概念,隱藏了它們在公共介面或API後面的內部工作。這使得每個模塊的功能易於使用和重構,獨立於其他任何模塊使用。

API

短用於應用程序編程介面,一個API是用於訪問操作系統,軟體應用程序或實用程序的功能的程序指令集和標准。軟體開發人員向公眾發布其API,以便其他開發人員可以在自己的項目中利用其產品的功能和服務。

回電話

一個回調是一塊多數民眾贊成作為參數傳遞給其他代碼語句通過可執行代碼,並預計「回調」,並在特定的時間執行。同步(或阻止)回調是即時的,而非同步(或延遲)回調意味著稍後發生。

程序化思維

程序化思維是開發人員和編程人員的核心思想,意味著通過將大問題分解成更小的離散步驟,將特定對象描述為計算機可以理解的明確定義的值來解決這些大問題。

關閉

以最簡單的形式描述閉包是函數中的一個函數,作為變數存儲。與普通函數不同,閉包擁有一個持久的作用域,即使在你的程序移出它們定義的代碼塊之後,它仍然保留在局部變數中。

編譯和解釋語言

編譯語言(比如C,C ++和Swift)要求你編譯代碼並將其構建成獨立的二進制應用程序,然後才能分發和運行。

解釋語言(如Python,PHP和javaScript)是由主機上的語言解釋器直接讀取代碼運行的,並向計算機提供指令以執行程序。

重構

代碼重構是重構現有代碼而不改變其外部行為的過程。重構通常用於改進軟體的非功能區域,或者改善特定軟體領域的性能或效用。

IDE

集成開發環境的簡稱,IDE是一種用於為特定語言開發的開發工具(或工具集合),包括代碼編輯器,編譯器,調試器和其他實用程序。流行的IDE包括蘋果公司的Xcode,微軟的Visual Studio以及IntelliJ,NetBeans和Eclipse等Java IDE。無論你的語言如何,都有一個IDE。

雖然這18個術語實際上只是開發人員的技術術語的表面,但是在您的編碼之旅中,您會發現他們所代表的概念非常重要。

Ⅲ js函數的幾種寫法 閉包概要

(就好像'stack-frame'是內存分配、而非處於堆棧!) 下面的代碼返回一個function的引用: Js代碼 function sayHello2(name) { var text = 'Hello ' + name; // local variable var sayAlert = function() { alert(text); } return sayAlert; } var say2 = sayHello2('Jane'); say2(); //hello Jane 多數JavaScript程序員能夠理解上面代碼的函數引用如何返回給變數。請在學習閉包之前理解它。

Ⅳ Python中什麼是閉包

閉包就是能夠讀取其他函數內部變數的函數。例如在javascript中,只有函數內部的子函數才能讀取局部變數,所以閉包可以理解成「定義在一個函數內部的函數「。在本質上,閉包是將函數內部和函數外部連接起來的橋梁。
閉包包含自由(未綁定到特定對象)變數,這些變數不是在這個代碼塊內或者任何全局上下文中定義的,而是在定義代碼塊的環境中定義(局部變數)。「閉包」 一詞來源於以下兩者的結合:要執行的代碼塊(由於自由變數被包含在代碼塊中,這些自由變數以及它們引用的對象沒有被釋放)和為自由變數提供綁定的計算環境(作用域)。在PHP、Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等語言中都能找到對閉包不同程度的支持。

Ⅳ javascript中的window.ActiveXObject和閉包是什麼意思有什麼作用,在哪些情況下使用啊

判斷瀏覽器是否支持ActiveX控制項

閉包的兩個特點:

1、作為一個函數變數的一個引用 - 當函數返回時,其處於激活狀態。

2、一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。

例1。

<scripttype="text/javascript">

functionsayHello2(name){

vartext='Hello'+name;//localvariable

varsayAlert=function(){alert(text);}

returnsayAlert;

}

varsy=sayHello2('never-online');

sy();

</script>

作為一個Javascript程序員,應該明白上面的代碼就是一個函數的引用。如果你還不明白或者不清楚的話,請先了解一些基本的知識,我這里不再敘述。

上面的代碼為什麼是一個閉包?

因為sayHello2函數里有一個內嵌匿名函數

sayAlert = function(){ alert(text); }

在Javascript里。如果你創建了一個內嵌函數(如上例),也就是創建了一個閉包。

在C或者其它的主流語言中,當一個函數返回後,所有的局部變數將不可訪問,因為它們所在的棧已經被消毀。但在Javascript里,如果你聲明了一個內嵌函數,局部變數將在函數返回後依然可訪問。比如上例中的變數sy,就是引用內嵌函數中的匿名函數function(){ alert(text); },可以把上例改成這樣:

<scripttype="text/javascript">

functionsayHello2(name){

vartext='Hello'+name;//localvariable

varsayAlert=function(){alert(text);}

returnsayAlert;

}

varsy=sayHello2('never-online');

alert(sy.toString());

</script>

這里也就與閉包的第二個特點相吻合。

例2。

<scripttype="text/javascript">

functionsay667(){

//

varnum=666;

varsayAlert=function(){alert(num);}

num++;

returnsayAlert;

}

varsy=say667();

sy();

alert(sy.toString());

</script>

上面的代碼中,匿名變數function() { alert(num); }中的num,並不是被拷貝,而是繼續引用外函數定義的局部變數——num中的值,直到外函數say667()返回。

例3。

<scripttype="text/javascript">

functionsetupSomeGlobals(){

//

varnum=666;

//

gAlertNumber=function(){alert(num);}

gIncreaseNumber=function(){num++;}

gSetNumber=function(x){num=x;}

}

</script>

<buttononclick="setupSomeGlobals()">生成-setupSomeGlobals()</button>

<buttononclick="gAlertNumber()">輸出值-gAlertNumber()</button>

<buttononclick="gIncreaseNumber()">增加-gIncreaseNumber()</button>

<buttononclick="gSetNumber(5)">賦值5-gSetNumber(5)</button>

上例中,gAlertNumber, gIncreaseNumber, gSetNumber都是同一個閉包的引用,setupSomeGlobals(),因為他們聲明都是通過同一個全局調用——setupSomeGlobals()。

你可以通過「生成」,「增加」,「賦值」,「輸出值」這三個按扭來查看輸出結果。如果你點擊「生成」按鈕,將創建一個新閉包。也就會重寫gAlertNumber(), gIncreaseNumber(), gSetNumber(5)這三個函數。

Ⅵ Javascript中的閉包是什麼意思

閉包的兩個特點:

1、作為一個函數變數的一個引用 - 當函數返回時,其處於激活狀態。

2、一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。

例1。

<scripttype="text/javascript">

functionsayHello2(name){

vartext='Hello'+name;//localvariable

varsayAlert=function(){alert(text);}

returnsayAlert;

}

varsy=sayHello2('never-online');

sy();

</script>

作為一個Javascript程序員,應該明白上面的代碼就是一個函數的引用。如果你還不明白或者不清楚的話,請先了解一些基本的知識,我這里不再敘述。

上面的代碼為什麼是一個閉包?

因為sayHello2函數里有一個內嵌匿名函數

sayAlert = function(){ alert(text); }

在Javascript里。如果你創建了一個內嵌函數(如上例),也就是創建了一個閉包。

在C或者其它的主流語言中,當一個函數返回後,所有的局部變數將不可訪問,因為它們所在的棧已經被消毀。但在Javascript里,如果你聲明了一個內嵌函數,局部變數將在函數返回後依然可訪問。比如上例中的變數sy,就是引用內嵌函數中的匿名函數function(){ alert(text); },可以把上例改成這樣:

<scripttype="text/javascript">

functionsayHello2(name){

vartext='Hello'+name;//localvariable

varsayAlert=function(){alert(text);}

returnsayAlert;

}

varsy=sayHello2('never-online');

alert(sy.toString());

</script>

這里也就與閉包的第二個特點相吻合。

例2。

<scripttype="text/javascript">

functionsay667(){

//

varnum=666;

varsayAlert=function(){alert(num);}

num++;

returnsayAlert;

}

varsy=say667();

sy();

alert(sy.toString());

</script>

上面的代碼中,匿名變數function() { alert(num); }中的num,並不是被拷貝,而是繼續引用外函數定義的局部變數——num中的值,直到外函數say667()返回。

例3。

<scripttype="text/javascript">

functionsetupSomeGlobals(){

//

varnum=666;

//

gAlertNumber=function(){alert(num);}

gIncreaseNumber=function(){num++;}

gSetNumber=function(x){num=x;}

}

</script>

<buttononclick="setupSomeGlobals()">生成-setupSomeGlobals()</button>

<buttononclick="gAlertNumber()">輸出值-gAlertNumber()</button>

<buttononclick="gIncreaseNumber()">增加-gIncreaseNumber()</button>

<buttononclick="gSetNumber(5)">賦值5-gSetNumber(5)</button>

上例中,gAlertNumber, gIncreaseNumber, gSetNumber都是同一個閉包的引用,setupSomeGlobals(),因為他們聲明都是通過同一個全局調用——setupSomeGlobals()。

你可以通過「生成」,「增加」,「賦值」,「輸出值」這三個按扭來查看輸出結果。如果你點擊「生成」按鈕,將創建一個新閉包。也就會重寫gAlertNumber(), gIncreaseNumber(), gSetNumber(5)這三個函數。

Ⅶ java程序員為什麼使用Groovy

正如Groovy對Java很多特性進行的包裝優化一樣,基於Groovy的HttpBuilder也包裹了HttpClient,使網路編程變得更加的方便易用,下面稍微來用一個例子看一下。
尋找各種依賴的jar包有時候會讓我們失去耐心,不過值得慶幸的是我們有Maven和Gradle這樣的工具,可以根據配置輕松的幫我們配置好我們需要的數據。下面我們來敘述一下整個過程。
1. 創建文件夾httpbuildertest
2. 創建gradle配置文件,build.gradle,內容如下:
apply plugin: "groovy"
apply plugin: "eclipse"

repositories {
mavenCentral()
}

dependencies {
compile "org.codehaus.groovy:http-builder:0.4.0"
compile "org.codehaus.groovy:groovy-all:2.3.3"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}

gradle我們將做另文介紹
3. 執行gralde eclipse(當然必須先安裝gradle),就可以生成eclipse所需要的.classpath和.project文件,這時候就可以使用eclipse導入功能來import->Existing Projects Into WorkSpace。
4. 創建我們的一個測試,試試看是不是可以使用httpbuilder了
import groovyx.net.http.HTTPBuilder
import spock.lang.Specification;
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*

class HttpbuildLabSpec extends Specification{
HTTPBuilder http = new HTTPBuilder( 'http://m.weather.com.cn' )
public void testRequestWeather(){
when:
def info =""
http.request( GET, JSON ) {
url.path = '/data/101290401.html'
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
response.success = { resp, json ->
info = json.weatherinfo.city
}
response.failure = { resp -> println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}" }
}
then: "曲靖"==info
}
}

打完收工,通過這個小例子我們可以了解到這么一些內容:
(1)HTTPBuilder 是這個框架的核心類(要不然怎麼和框架一個名字),構建這個類的對象的時候,指定要請求的baseUrl。
(2)request方法可以指定請求的method和返回的數據格式,method對應的是GET/PUT/POST/DELETE/HEAD幾個常量,而數據格式目前有JSON/XML/HTML/BINARY/URLENC/ANY幾種。
(3)一個比較有意思的地方是,在http的request方法裡面,彷彿是無根之水一樣突然冒出來了幾個沒有聲明過的變數,看起來連編譯也不會通過的方法,那麼是如何能正常運作的呢?這個我們就要研究到Groovy的Closure(閉包)。Groovy的閉包里包含有一個delegate屬性,一般來說,這個delegate里保存的是閉包使用上下文的對象引用,比如a調用了一個閉包b,則b的delegate就是a的this對象。而在HTTPBuilder對象調用request方法的時候,它把傳入閉包的delegate改成了一個叫做SendDelegate的類對象(這是HTTPBuilder的內部類,他們都是用Java寫的,在新版的HttpBuilder里,已經改名為RequestConfigDelegate),這個類裡面,分別包含了一個叫做getHeaders()的方法,一個叫做getUrL()的方法,一個叫做getResponse()的方法。稍微思索一下我們就可以想到,Groovy里有這樣的特性,如果直接使用一個識別不出來的變數,Groovy會假設它是getter的一種簡寫形式,自動進行補全(當然這也是DSL的常用伎倆,把方法偽裝成短語),而getter並沒有參數,所以其括弧是可以簡寫的,實際上上面的代碼可以寫作getUrl().path = '/data/101290401.html',這樣就非常符合程序員的視覺體驗了。
(4)主要是為了喜歡追根問題的同學釋疑,實際上整個調用還是非常的簡單明快的,在request閉包里,我們通過response(記得嗎,實際上就是GetResponse()),獲得了一個Map結構,這個Map的內部結構實際上是Map<String,Closure>,對「success」和「failure」這兩個key我們分別設置了對應的閉包,這樣就完成了回調的設置,一旦方法成功或者失敗,就可以調用到對應的閉包。
(5)使用了JSON作為返回格式,閉包的第二個參數就是解析好的返回body,就是一個Json對象,是可以直接用點號來訪問的。當然最好不要在失敗的閉包里放這個參數,一般失敗的情況比較多,也許就是一個html返回,格式錯誤那麼測試也就無法按照預期進行了。

Ⅷ 什麼地方有關於閉包方面的書籍

最近在網上查閱了不少Javascript閉包(closure)相關的資料,寫的大多是非常的學術和專業。對於初學者來說別說理解閉包了,就連文字敘述都很難看懂。撰寫此文的目的就是用最通俗的文字揭開Javascript閉包的真實面目。

一、什麼是閉包?
「官方」的解釋是:所謂「閉包」,指的是一個擁有許多變數和綁定了這些變數的環境的表達式(通常是一個函數),因而這些變數也是該表達式的一部分。
相信很少有人能直接看懂這句話,因為他描述的太學術。我想用如何在Javascript中創建一個閉包來告訴你什麼是閉包,因為跳過閉包的創建過程直接理解閉包的定義是非常困難的。看下面這段代碼:
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
這段代碼有兩個特點:
1、函數b嵌套在函數a內部;
2、函數a返回函數b。
這樣在執行完var c=a()後,變數c實際上是指向了函數b,再執行c()後就會彈出一個窗口顯示i的值(第一次為1)。這段代碼其實就創建了一個閉包,為什麼?因為函數a外的變數c引用了函數a內的函數b,就是說:

當函數a的內部函數b被函數a外的一個變數引用的時候,就創建了一個閉包。

我猜想你一定還是不理解閉包,因為你不知道閉包有什麼作用,下面讓我們繼續探索。

二、閉包有什麼作用?
簡而言之,閉包的作用就是在a執行完並返回後,閉包使得Javascript的垃圾回收機制GC不會收回a所佔用的資源,因為a的內部函數b的執行需要依賴a中的變數。這是對閉包作用的非常直白的描述,不專業也不嚴謹,但大概意思就是這樣,理解閉包需要循序漸進的過程。
在上面的例子中,由於閉包的存在使得函數a返回後,a中的i始終存在,這樣每次執行c(),i都是自加1後alert出i的值。

那 么我們來想像另一種情況,如果a返回的不是函數b,情況就完全不同了。因為a執行完後,b沒有被返回給a的外界,只是被a所引用,而此時a也只會被b引 用,因此函數a和b互相引用但又不被外界打擾(被外界引用),函數a和b就會被GC回收。(關於Javascript的垃圾回收機制將在後面詳細介紹)

三、閉包內的微觀世界
如果要更加深入的了解閉包以及函數a和嵌套函數b的關系,我們需要引入另外幾個概念:函數的執行環境(excution context)、活動對象(call object)、作用域(scope)、作用域鏈(scope chain)。以函數a從定義到執行的過程為例闡述這幾個概念。

1、當定義函數a的時候,js解釋器會將函數a的作用域鏈(scope chain)設置為定義a時a所在的「環境」,如果a是一個全局函數,則scope chain中只有window對象。
2、當函數a執行的時候,a會進入相應的執行環境(excution context)。
3、在創建執行環境的過程中,首先會為a添加一個scope屬性,即a的作用域,其值就為第1步中的scope chain。即a.scope=a的作用域鏈。
4、然後執行環境會創建一個活動對象(call object)。活動對象也是一個擁有屬性的對象,但它不具有原型而且不能通過JavaScript代碼直接訪問。創建完活動對象後,把活動對象添加到a的作用域鏈的最頂端。此時a的作用域鏈包含了兩個對象:a的活動對象和window對象。
5、下一步是在活動對象上添加一個arguments屬性,它保存著調用函數a時所傳遞的參數。
6、最後把所有函數a的形參和內部的函數b的引用也添加到a的活動對象上。在這一步中,完成了函數b的的定義,因此如同第3步,函數b的作用域鏈被設置為b所被定義的環境,即a的作用域。

到此,整個函數a從定義到執行的步驟就完成了。此時a返回函數b的引用給c,又函數b的作用域鏈包含了對函數a的活動對象的引用,也就是說b可以訪問到a中定義的所有變數和函數。函數b被c引用,函數b又依賴函數a,因此函數a在返回後不會被GC回收。

當函數b執行的時候亦會像以上步驟一樣。因此,執行時b的作用域鏈包含了3個對象:b的活動對象、a的活動對象和window對象.

當在函數b中訪問一個變數的時候,搜索順序是先搜索自身的活動對象,如果存在則返回,如果不存在將繼續搜索函數a的活動對象,依次查找,直到找到為止。如果整個作用域鏈上都無法找到,則返回undefined。如果函數b存在prototype原型對象,則在查找完自身的活動對象 後先查找自身的原型對象,再繼續查找。這就是Javascript中的變數查找機制。

閱讀全文

與程序員閉包講解相關的資料

熱點內容
自己購買雲主伺服器推薦 瀏覽:420
個人所得稅java 瀏覽:761
多餘的伺服器滑道還有什麼用 瀏覽:190
pdf劈開合並 瀏覽:28
不能修改的pdf 瀏覽:752
同城公眾源碼 瀏覽:489
一個伺服器2個埠怎麼映射 瀏覽:297
java字元串ascii碼 瀏覽:79
台灣雲伺服器怎麼租伺服器 瀏覽:475
旅遊手機網站源碼 瀏覽:332
android關聯表 瀏覽:945
安卓導航無聲音怎麼維修 瀏覽:332
app怎麼裝視頻 瀏覽:430
安卓系統下的軟體怎麼移到桌面 瀏覽:96
windows拷貝到linux 瀏覽:772
mdr軟體解壓和別人不一樣 瀏覽:904
單片機串列通信有什麼好處 瀏覽:340
游戲開發程序員書籍 瀏覽:860
pdf中圖片修改 瀏覽:288
匯編編譯後 瀏覽:491