国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【JS. ES5重點筆記】執行環境和作用域

Jeffrrey / 3159人閱讀

摘要:作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。這樣,一直延續到全局執行環境全局執行環境的變量對象始終都是作用域鏈中的最后一個對象。如果在局部環境中沒有找到該變量名,則繼續沿作用域鏈向上搜索。

【JavaScript.ES5】執行環境和作用域

參考文獻:

Nicholas C.Zakas 《JavaScript》高級程序設計

僅為個人學習參考文獻的內容記錄的筆記。存在部分直接拿來的成分。不得不說,這本書寫得很透徹。

引言和基本概念

執行環境是JS中很重要的概念,其定義了變量或者函數訪問其他數據的權限,決定了其各自的行為。

每個函數都有自己的執行環境。當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。而在函數執行之后,棧將其環境彈出,把控制權返回給之前的執行環境。 ECMAScript 程序中的執行流正是由這個方便的機制控制著。

當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈(scope chain)。作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。作用域鏈的前端,始終都是當前執行的代碼所在環境的變量對象。如果這個環境是函數,則將其活動對象(activation object)作為變量對象。活動對象在最開始時只包含一個變量,即 arguments 對象(這個對象在全局環境中是不存在的)。作用域鏈中的下一個變量對象來自包含(外部)環境,而再下一個變量對象則來自下一個包含環境。這樣,一直延續到全局執行環境;全局執行環境的變量對象始終都是作用域鏈中的最后一個對象。

標識符解是沿著作用域鏈一級一級往下拓展的,而搜素則是從作用域鏈的前端開始逐級回溯,直到找到標識符為止(找不到的話當然就報錯了)。

下面請看簡單的事例:

var color = "blue";

function changeColor(){
    if (color === "blue"){
        color = "red";
    } else {
        color = "blue";
        }
    }

changeColor();

alert("Color is now " + color);

通過運行可以發現,存行結果是紅色,運行changecolor時,會去搜索color的值,在函數體內,未發現color的定義,于是會往外找,結果找到了color="blue"的定義,于是就會訪問,獲取,修改。

var color = "blue";

function changeColor(){
    var anotherColor = "red";

    function swapColors(){
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
        
        //color, anotherColor, and tempColor are all accessible here
    }

    //color and anotherColor are accessible here, but not tempColor        
    swapColors();
}

changeColor();

//anotherColor and tempColor aren"t accessible here, but color is
alert("Color is now " + color);

上面涉及了3個執行環境,全局、changecolor()和swapColors三種。其中全局變量是color和anotherColor。changeColor()的局部環境中有一個名為anotherColor 的變量和一個名為swapColors()的函數,但它也可以訪問全局環境中的變量 color。 swapColors()的局部環境中有一個變量tempColor,該變量只能在這個環境中訪問到。無論全局環境還是 changeColor()的局部環境都無權訪問 tempColor。然而,在 swapColors()內部則可以訪問其他兩個環境中的所有變量,因為那兩個環境是它的父執行環境。

延長作用域鏈

下列兩種情況可以延長作用域鏈:

try-catch語句的catch語句塊

with語句

這兩個語句都會在作用域鏈的前端添加一個變量對象。對 with 語句來說,會將指定的對象添加到作用域鏈中。對 catch 語句來說,會創建一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明。

function buildUrl() {
    var qs = "?debug=true";

    with(location){
        var url = href + qs;        
    }

    return url;
}

var result = buildUrl();
alert(result);

with接受了location對象,于是變量對象就是location的所有屬性和方法,變量對象就被添加在作用域鏈前端。buildUrl()函數中有局部變量qs。with引用變量href時,即location.href,能夠被找到。引用變量qs,指的則是buildUrl()函數內部的qs。至于 with 語句內部,則定義了一個名為 url 的變量,因而 url 就成了函數執行環境的一部分,所以可以作為函數的值被返回。

沒有塊級的作用域

JS中并沒有塊級作用域。在類C語言中是有的,如條件語句,循環語句之類,大括號內屬于一種作用域,但是在JS中并沒有。

if (true) {
var color = "blue";
}

alert(color); //"blue"

顯然,color在條件語句的大括號中,var定義的也是局部變量,但實際上,大括號外面能訪問到想訪問的color。

聲明變量

使用 var 聲明的變量會自動被添加到最接近的環境中。而且僅限于該環境。反之,如果該聲明沒有帶,var會被自動認為是全局變量。

function add(num1, num2) {
    var sum = num1 + num2;
    return sum;
}

var result = add(10, 20); //30
alert(sum);

這里報錯了,因為sum在add函數中為局部變量,從大括號外面并不能訪問到sum。如果改成下面這樣,就能正常運行。

function add(num1, num2) {
    sum = num1 + num2;
    return sum;
}

var result = add(10, 20); //30
alert(sum); //30
查詢標識符

當在某個環境中為了讀取或寫入而引用一個標識符時,必須通過搜索來確定該標識符實際代表什么。搜索過程從作用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符。如果在局部環境中找到了該標識符,搜索過程停止,變量就緒。如果在局部環境中沒有找到該變量名,則繼續沿作用域鏈向上搜索。搜索過程將一直追溯到全局環境的變量對象。如果在全局環境中也沒有找到這個標識符,則意味著該變量尚未聲明,會報錯。

var color = "blue";

function getColor(){
    return color;
}

alert(getColor()); //"blue"

alert中調用了getcolor()函數,這個函數中訪問了color,然而函數中并沒有聲明color,于是會向上找color,在全局中找到了,于是就取值。

var color = "blue";

function getColor(){
    var color = "red";
    return color;
}

alert(getColor()); //"red"
alert(color);//"blue"

getcolor函數體內有color的聲明,而且是局部的,所以并不會覆蓋全局的blue。在getcolor內部,color就是內部聲明的color,一旦搜索到定義之后就不會再搜索,所以就是red;而外面的color則并不會因為里面的color是red而改變,所以還是blue。

補充: 變量查詢也不是沒有代價的。很明顯,訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 JavaScript 引擎在優化標識符查詢方面做得不錯,因此這個差別在將來恐怕就可以忽略不計了。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82517.html

相關文章

  • 《ECMAScript 6 入門》讀書筆記

    摘要:阮一峰老師開源作品。書上的示例代碼可以通過在線網站代碼調試工具調試。 阮一峰老師開源作品。 書上的示例代碼可以通過 在線網站代碼調試工具 JS Bin 調試。 作用域 作用域鏈 每個變量或函數通過執行環境 (execution context) 定義了其有權訪問的其他數據,決定了他們各自的行為; 全局執行環境是最頂層的執行環境,根據宿主環境的不同,表示全局執行環境的對象也不同:在瀏覽...

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

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

    galaxy_robot 評論0 收藏0
  • JavaScript 語言核心筆記(持續更新)

    摘要:在同一個塊內,不允許用重復聲明變量。中為新增了塊級作用域。自帶遍歷器的對象有數組字符串類數組對象對象的對象等和結構對象。返回一個遍歷器,使遍歷數組的鍵值對鍵名鍵值。 目錄 1.語法 2.類型、值和變量 3.表達式和運算符 4.語句 5.數組 6.對象 7.函數 8.全局屬性和方法 9.詞法作用域、作用域鏈、閉包 10.原型鏈、繼承機制 11.this的理解 12.ES5新特性 13.E...

    suosuopuo 評論0 收藏0
  • [譯] ES6 學習筆記:關于 ES2015 特性的詳細概述

    摘要:將轉換成常見的使用實現的基于迭代器的迭代。處停止迭代器基于鴨子模型接口這里使用語法僅僅為了說明問題使用支持為了使用迭代器屬性需要引入。生成器是迭代器的子類,包含了附加的與。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,請把star獻給他,你可以在此嘗試這些特性REPL。 概述 ECMAScr...

    leoperfect 評論0 收藏0
  • 【進階1-1期】理解JavaScript 中的執行上下文執行

    摘要:首次運行代碼時,會創建一個全局執行上下文并到當前的執行棧中。執行上下文的創建執行上下文分兩個階段創建創建階段執行階段創建階段確定的值,也被稱為。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,,今天是第一天 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進...

    import. 評論0 收藏0

發表評論

0條評論

Jeffrrey

|高級講師

TA的文章

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