真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JavaScript閉包與作用域鏈怎么定義

這篇文章主要講解了“JavaScript閉包與作用域鏈怎么定義”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JavaScript閉包與作用域鏈怎么定義”吧!

成都創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、澄海網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為澄海等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

閉包定義

閉包指的是有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在一個(gè)函數(shù)A內(nèi)部創(chuàng)建另一個(gè)函數(shù)B,那么函數(shù)B就是一個(gè)閉包,可以訪問函數(shù)A作用域中的所有變量。

JavaScript的閉包與作用域鏈密不可分,因此本文可以和JavaScript的作用域鏈相對照分析,一定可以對JavaScript的閉包和作用域鏈有更深的理解。

下面我們?nèi)匀灰詂reateComparisonFunction為例進(jìn)行閉包的分析。

//step1: define createComparisonFunction
function createComparisonFunction(propertyName){
  return function(object1, object2){
    var value1 = object1[propertyName];
    var value2 = object2[propertyName];
    if (value1 < value2) {
      return -1;
    } else if (value1 > value2) {
      return 1;
    } else {
      return 0;
    }
  };
}
//step2: call createComparisonFunction
var compareName = createComparisonFunction("name");
var compareAge = createComparisonFunction("age");
//step3: call compare
var object1 = {
  name : "Nicholas",
  age : 25
};
var object2 = {
  name : "Greg",
  age : 27
};
var result1 = compareName(object1, object2); // 1
var result2 = compareAge(object1, object2); // -1
//step4: dereference closure for recycle memory
compareName = null;
compareAge = null;

在這個(gè)例子中,匿名函數(shù)function(object1, object2)是一個(gè)閉包,能訪問createComparisonFunction作用域里的所有變量,自然也包含propertyName屬性, 因?yàn)閜ropertyName參數(shù)的不同,導(dǎo)致比較的屬性也有所不同,從而函數(shù)執(zhí)行結(jié)果也有不同。

閉包與變量

從JavaScript的作用域鏈中,我們了解到JavaScript是通過作用域鏈來確定函數(shù)執(zhí)行環(huán)境的作用域的,這種機(jī)制會引出一個(gè)值得注意的副作用,即閉包只能取得包含函數(shù)中任何變量的最后一個(gè)值。閉包是通過引用外部函數(shù)的活動(dòng)對象來訪問該活動(dòng)對象中的所有變量,因此在外部函數(shù)執(zhí)行過程中,這些變量的值可能會變化,但是在外部函數(shù)執(zhí)行完畢之后,外部函數(shù)的活動(dòng)對象便不會再改變,因此在執(zhí)行閉包的時(shí)候,閉包通過作用域鏈訪問到外部函數(shù)的活動(dòng)對象中的所有變量都只可能是在外部函數(shù)執(zhí)行完畢之后,外部函數(shù)的活動(dòng)對象中最后所保存的值。我們通過一個(gè)例子來說明這種副作用。

function createFunctions(){
  var result = new Array();
  for (var i = 0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }
  return result;
}
var functions = createFunctions();
for(var i = 0; i < functions.length; i++){
  console.log(functions[i]());
}

輸出的結(jié)果是

10 10 10 10 10 10 10 10 10 10

從表面上看,似乎每個(gè)函數(shù)都應(yīng)該返回自己的索引值,但實(shí)際上,每個(gè)函數(shù)都返回10。因?yàn)槊總€(gè)函數(shù)的作用域鏈中都保存著createFunctions函數(shù)的活動(dòng)對象,所以他們引用的都是這個(gè)createFunctions函數(shù)的活動(dòng)對象中的變量i,在createFunctions函數(shù)返回之后,變量i的值是10,此時(shí)每個(gè)函數(shù)都引用著保存變量i的同一個(gè)變量對象,所以每個(gè)函數(shù)內(nèi)部i的值都是10。

我們以調(diào)用functions[3]()為例,圖解一下:

JavaScript閉包與作用域鏈怎么定義

Closure函數(shù)的Function對象的作用域鏈引用的createFunctions的活動(dòng)對象中保留的變量i的值為10。所以不管是functions[3]()還是functions[5](),其運(yùn)行時(shí)上下文的作用域鏈引用的createFunctions的活動(dòng)對象都是同一個(gè)活動(dòng)對象,該活動(dòng)對象中保留的變量i的值是10。

如何避免這種局面?我們可以通過創(chuàng)建另一個(gè)匿名函數(shù)讓閉包的行為符合預(yù)期。

function createFunctions(){
  var result = new Array();
  for (var i = 0; i < 10; i++){
    result[i] = function(num){
      return function(){
        return num;
      }
    }(i);
  }
  return result;
}
var functions = createFunctions();
for(var i = 0; i < functions.length; i++){
  console.log(functions[i]());
}

輸出的結(jié)果是

0 1 2 3 4 5 6 7 8 9

這個(gè)代碼片段與前面的代碼的區(qū)別在于立即調(diào)用了一個(gè)匿名函數(shù)function(num),使得閉包function()引用的是function(num)的活動(dòng)對象,訪問的是該活動(dòng)對象中的變量num而不是createFunctions活動(dòng)對象中的變量i,而在立即調(diào)用function(num)的num是索引值0,1,2…9。

我們?nèi)耘f以調(diào)用functions[3]()為例,圖解一下:

JavaScript閉包與作用域鏈怎么定義

在執(zhí)行createFunctions函數(shù)的時(shí)候,會依次調(diào)用function(0), function(1) … function(9), 生成function(0), function(1) … function(9)這10個(gè)function(num)的活動(dòng)對象,而result[0], result[1] … result[9]這10個(gè)匿名函數(shù)對象的作用域鏈分別引用這10個(gè)function(num)的活動(dòng)對象,而其中的變量num的值也對應(yīng)的為0, 1 … 9。

所以不管是functions[3]()還是functions[5](),其運(yùn)行時(shí)上下文的作用域鏈都會引用在執(zhí)行createFunctions函數(shù)時(shí)候所執(zhí)行的function(3)或者function(5)這些function(num)函數(shù)的活動(dòng)對象,這些活動(dòng)對象都是不同的活動(dòng)對象,其中保留的num值分別為3, 5。

感謝各位的閱讀,以上就是“JavaScript閉包與作用域鏈怎么定義”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對JavaScript閉包與作用域鏈怎么定義這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!


本文標(biāo)題:JavaScript閉包與作用域鏈怎么定義
分享地址:http://weahome.cn/article/ijepjj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部