成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript中詞法作用域、閉包與跳出閉包

lykops / 3172人閱讀

摘要:是典型的詞法作用域的語言,即一個符號參照到語境中符號名字出現(xiàn)的地方,局部變量缺省有著詞法作用域。沒有任何自己的局部變量,然而它可以訪問到外部函數(shù)的變量,即可以使用父函數(shù)中聲明的變量。通常,函數(shù)中的局部變量僅在函數(shù)的執(zhí)行期間可用。

本文從屬于筆者的JavaScript 入門與最佳實踐系列文章,同時,本部分內(nèi)容也歸納于筆者的我的校招準備之路:從Web前端到服務(wù)端應(yīng)用架構(gòu)這篇綜述。

大部分人都會做錯的經(jīng)典JS閉包面試題
how-do-javascript-closures-work

Lexical Scope:詞法作用域

functions are executed using the scope chain that was in effect when they were defined

一般來說,在編程語言里我們常見的變量作用域就是詞法作用域與動態(tài)作用域(Dynamic Scope),絕大部分的編程語言都是使用的詞法作用域。詞法作用域注重的是所謂的Write-Time,即編程時的上下文,而動態(tài)作用域以及常見的this的用法,都是Run-Time,即運行時上下文。詞法作用域關(guān)注的是函數(shù)在何處被定義,而動態(tài)作用域關(guān)注的是函數(shù)在何處被調(diào)用。JavaScript是典型的詞法作用域的語言,即一個符號參照到語境中符號名字出現(xiàn)的地方,局部變量缺省有著詞法作用域。此二者的對比可以參考如下這個例子:

function foo() {
    console.log( a ); // 2 in Lexical Scope ,But 3 in Dynamic Scope
}

function bar() {
    var a = 3;
    foo();
}

var a = 2;

bar();

看一個實例如下:

var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

該代碼片最終輸出的結(jié)果是:

I am just a local
Closure

閉包本身是含有自由變量的代碼塊,在JavaScript中我們常用的閉包則是本身的詞法作用域與變量保留相結(jié)合的表現(xiàn),首先回顧下一個基本的詞法作用域的用法:

function init() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  displayName();
}
init();

函數(shù) init() 創(chuàng)建了一個局部變量 name,然后定義了名為 displayName() 的函數(shù)。displayName() 是一個內(nèi)部函數(shù)——定義于 init() 之內(nèi)且僅在該函數(shù)體內(nèi)可用。displayName() 沒有任何自己的局部變量,然而它可以訪問到外部函數(shù)的變量,即可以使用父函數(shù)中聲明的 name 變量。注意,這里是直接執(zhí)行外部的init函數(shù),下面看一個閉包的例子:

function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

運行這段代碼的效果和之前的 init() 示例完全一樣:字符串 "Mozilla" 將被顯示在一個 JavaScript 警告框中。其中的不同 — 也是有意思的地方 — 在于 displayName() 內(nèi)部函數(shù)在執(zhí)行前被從其外圍函數(shù)中返回了。這段代碼看起來別扭卻能正常運行。通常,函數(shù)中的局部變量僅在函數(shù)的執(zhí)行期間可用。一旦 makeFunc() 執(zhí)行過后,我們會很合理的認為 name 變量將不再可用。雖然代碼運行的沒問題,但實際并不是這樣的。這個謎題的答案是 myFunc 變成一個閉包了。 閉包是一種特殊的對象。它由兩部分構(gòu)成:函數(shù),以及創(chuàng)建該函數(shù)的環(huán)境。環(huán)境由閉包創(chuàng)建時在作用域中的任何局部變量組成。在我們的例子中,myFunc 是一個閉包,由 displayName 函數(shù)和閉包創(chuàng)建時存在的 "Mozilla" 字符串形成。

避免閉包

在真實的開發(fā)中我們常常會使用閉包這一變量保留的特性來傳遞變量到異步函數(shù)中,不過閉包也往往會使程序出乎我們的控制,譬如在下面這個簡單的循環(huán)中,我們本希望能夠打印出0~9這幾個數(shù):

for(var i = 0;i < 10;i++){
   setTimeout(()=>{console.log(i),1000})
}

不過所有輸入的i的值都是10,這與我們的期望產(chǎn)生了很大的偏差。因此我們在部分情況下需要破壞閉包而獲取真實的變量值。

將異步獲取值保留到新增的閉包中

我們可以考慮加一層閉包,將i以函數(shù)參數(shù)形式傳遞給內(nèi)層函數(shù):

    function init3() {     
      var pAry = document.getElementsByTagName("p");     
      for( var i=0; i

或者在新增的閉包中將i以局部變量形式傳遞給內(nèi)部函數(shù)中:

    function init4() {     
      var pAry = document.getElementsByTagName("p");     
      for( var i=0; i
將變量值保留到作用域之外

在DOM環(huán)境中,我們可以將變量值存儲到要操作的DOM對象中:

    function init() {     
      var pAry = document.getElementsByTagName("p");     
      for( var i=0; i

也可以將變量i保存在匿名函數(shù)本身:

    function init2() {     
      var pAry = document.getElementsByTagName("p");     
      for( var i=0; i

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80118.html

相關(guān)文章

  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • 還擔心面試官問閉包

    摘要:一言以蔽之,閉包,你就得掌握。當函數(shù)記住并訪問所在的詞法作用域,閉包就產(chǎn)生了。所以閉包才會得以實現(xiàn)。從技術(shù)上講,這就是閉包。執(zhí)行后,他的內(nèi)部作用域并不會消失,函數(shù)依然保持有作用域的閉包。 網(wǎng)上總結(jié)閉包的文章已經(jīng)爛大街了,不敢說筆者這篇文章多么多么xxx,只是個人理解總結(jié)。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結(jié)與《JavaScript忍者秘籍》 《你不知道的JavaScri...

    tinyq 評論0 收藏0
  • JavaScript基礎(chǔ)系列---閉包及其應(yīng)用

    摘要:所以,有另一種說法認為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。所以本文中將以維基百科中的定義為準即在計算機科學(xué)中,閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。 閉包(closure)是JavaScript中一個神秘的概念,許多人都對它難以理解,我也一直處于似懂非懂的狀態(tài),前幾天深入了解了一下執(zhí)行環(huán)境以及作用域鏈,可戳查看詳情,而閉包與作用域及作用域鏈的關(guān)系密不可分,所...

    leoperfect 評論0 收藏0
  • 閉包詳解一

    摘要:再看一段代碼這樣就清晰地展示了閉包的詞法作用域能訪問的作用域?qū)斪鲆粋€值返回執(zhí)行后,將的引用賦值給執(zhí)行,輸出了變量我們知道通過引用的關(guān)系,就是函數(shù)本身。 在正式學(xué)習閉包之前,請各位同學(xué)一定要確保自己對詞法作用域已經(jīng)非常的熟悉了,如果對詞法作用域還不夠熟悉的話,可以先看: 深入理解閉包之前置知識---作用域與詞法作用域 前言 現(xiàn)在去面試前端開發(fā)的崗位,如果你的面試官也是個前端,并且不是太...

    cnio 評論0 收藏0
  • 《你不知道的javascript》筆記_作用閉包

    摘要:建筑的頂層代表全局作用域。實際的塊級作用域遠不止如此塊級作用域函數(shù)作用域早期盛行的立即執(zhí)行函數(shù)就是為了形成塊級作用域,不污染全局。這便是閉包的特點吧經(jīng)典面試題下面的代碼輸出內(nèi)容答案個如何處理能夠輸出閉包方式方式下一篇你不知道的筆記 下一篇:《你不知道的javascript》筆記_this 寫在前面 這一系列的筆記是在《javascript高級程序設(shè)計》讀書筆記系列的升華版本,旨在將零碎...

    galaxy_robot 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<