成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【JS. ES5重點(diǎn)筆記】執(zhí)行環(huán)境和作用域

Jeffrrey / 3209人閱讀

摘要:作用域鏈的用途,是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象。如果在局部環(huán)境中沒(méi)有找到該變量名,則繼續(xù)沿作用域鏈向上搜索。

【JavaScript.ES5】執(zhí)行環(huán)境和作用域

參考文獻(xiàn):

Nicholas C.Zakas 《JavaScript》高級(jí)程序設(shè)計(jì)

僅為個(gè)人學(xué)習(xí)參考文獻(xiàn)的內(nèi)容記錄的筆記。存在部分直接拿來(lái)的成分。不得不說(shuō),這本書寫得很透徹。

引言和基本概念

執(zhí)行環(huán)境是JS中很重要的概念,其定義了變量或者函數(shù)訪問(wèn)其他數(shù)據(jù)的權(quán)限,決定了其各自的行為。

每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí),函數(shù)的環(huán)境就會(huì)被推入一個(gè)環(huán)境棧中。而在函數(shù)執(zhí)行之后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。 ECMAScript 程序中的執(zhí)行流正是由這個(gè)方便的機(jī)制控制著。

當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈(scope chain)。作用域鏈的用途,是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的所有變量和函數(shù)的有序訪問(wèn)。作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象(activation object)作為變量對(duì)象。活動(dòng)對(duì)象在最開(kāi)始時(shí)只包含一個(gè)變量,即 arguments 對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)。作用域鏈中的下一個(gè)變量對(duì)象來(lái)自包含(外部)環(huán)境,而再下一個(gè)變量對(duì)象則來(lái)自下一個(gè)包含環(huán)境。這樣,一直延續(xù)到全局執(zhí)行環(huán)境;全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象。

標(biāo)識(shí)符解是沿著作用域鏈一級(jí)一級(jí)往下拓展的,而搜素則是從作用域鏈的前端開(kāi)始逐級(jí)回溯,直到找到標(biāo)識(shí)符為止(找不到的話當(dāng)然就報(bào)錯(cuò)了)。

下面請(qǐng)看簡(jiǎn)單的事例:

var color = "blue";

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

changeColor();

alert("Color is now " + color);

通過(guò)運(yùn)行可以發(fā)現(xiàn),存行結(jié)果是紅色,運(yùn)行changecolor時(shí),會(huì)去搜索color的值,在函數(shù)體內(nèi),未發(fā)現(xiàn)color的定義,于是會(huì)往外找,結(jié)果找到了color="blue"的定義,于是就會(huì)訪問(wèn),獲取,修改。

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個(gè)執(zhí)行環(huán)境,全局、changecolor()和swapColors三種。其中全局變量是color和anotherColor。changeColor()的局部環(huán)境中有一個(gè)名為anotherColor 的變量和一個(gè)名為swapColors()的函數(shù),但它也可以訪問(wèn)全局環(huán)境中的變量 color。 swapColors()的局部環(huán)境中有一個(gè)變量tempColor,該變量只能在這個(gè)環(huán)境中訪問(wèn)到。無(wú)論全局環(huán)境還是 changeColor()的局部環(huán)境都無(wú)權(quán)訪問(wèn) tempColor。然而,在 swapColors()內(nèi)部則可以訪問(wèn)其他兩個(gè)環(huán)境中的所有變量,因?yàn)槟莾蓚€(gè)環(huán)境是它的父執(zhí)行環(huán)境。

延長(zhǎng)作用域鏈

下列兩種情況可以延長(zhǎng)作用域鏈:

try-catch語(yǔ)句的catch語(yǔ)句塊

with語(yǔ)句

這兩個(gè)語(yǔ)句都會(huì)在作用域鏈的前端添加一個(gè)變量對(duì)象。對(duì) with 語(yǔ)句來(lái)說(shuō),會(huì)將指定的對(duì)象添加到作用域鏈中。對(duì) catch 語(yǔ)句來(lái)說(shuō),會(huì)創(chuàng)建一個(gè)新的變量對(duì)象,其中包含的是被拋出的錯(cuò)誤對(duì)象的聲明。

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

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

    return url;
}

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

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

沒(méi)有塊級(jí)的作用域

JS中并沒(méi)有塊級(jí)作用域。在類C語(yǔ)言中是有的,如條件語(yǔ)句,循環(huán)語(yǔ)句之類,大括號(hào)內(nèi)屬于一種作用域,但是在JS中并沒(méi)有。

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

alert(color); //"blue"

顯然,color在條件語(yǔ)句的大括號(hào)中,var定義的也是局部變量,但實(shí)際上,大括號(hào)外面能訪問(wèn)到想訪問(wèn)的color。

聲明變量

使用 var 聲明的變量會(huì)自動(dòng)被添加到最接近的環(huán)境中。而且僅限于該環(huán)境。反之,如果該聲明沒(méi)有帶,var會(huì)被自動(dòng)認(rèn)為是全局變量。

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

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

這里報(bào)錯(cuò)了,因?yàn)閟um在add函數(shù)中為局部變量,從大括號(hào)外面并不能訪問(wèn)到sum。如果改成下面這樣,就能正常運(yùn)行。

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

var result = add(10, 20); //30
alert(sum); //30
查詢標(biāo)識(shí)符

當(dāng)在某個(gè)環(huán)境中為了讀取或?qū)懭攵靡粋€(gè)標(biāo)識(shí)符時(shí),必須通過(guò)搜索來(lái)確定該標(biāo)識(shí)符實(shí)際代表什么。搜索過(guò)程從作用域鏈的前端開(kāi)始,向上逐級(jí)查詢與給定名字匹配的標(biāo)識(shí)符。如果在局部環(huán)境中找到了該標(biāo)識(shí)符,搜索過(guò)程停止,變量就緒。如果在局部環(huán)境中沒(méi)有找到該變量名,則繼續(xù)沿作用域鏈向上搜索。搜索過(guò)程將一直追溯到全局環(huán)境的變量對(duì)象。如果在全局環(huán)境中也沒(méi)有找到這個(gè)標(biāo)識(shí)符,則意味著該變量尚未聲明,會(huì)報(bào)錯(cuò)。

var color = "blue";

function getColor(){
    return color;
}

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

alert中調(diào)用了getcolor()函數(shù),這個(gè)函數(shù)中訪問(wèn)了color,然而函數(shù)中并沒(méi)有聲明color,于是會(huì)向上找color,在全局中找到了,于是就取值。

var color = "blue";

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

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

getcolor函數(shù)體內(nèi)有color的聲明,而且是局部的,所以并不會(huì)覆蓋全局的blue。在getcolor內(nèi)部,color就是內(nèi)部聲明的color,一旦搜索到定義之后就不會(huì)再搜索,所以就是red;而外面的color則并不會(huì)因?yàn)槔锩娴腸olor是red而改變,所以還是blue。

補(bǔ)充: 變量查詢也不是沒(méi)有代價(jià)的。很明顯,訪問(wèn)局部變量要比訪問(wèn)全局變量更快,因?yàn)椴挥孟蛏纤阉髯饔糜蜴湣?JavaScript 引擎在優(yōu)化標(biāo)識(shí)符查詢方面做得不錯(cuò),因此這個(gè)差別在將來(lái)恐怕就可以忽略不計(jì)了。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/82517.html

相關(guān)文章

  • 《ECMAScript 6 入門》讀書筆記

    摘要:阮一峰老師開(kāi)源作品。書上的示例代碼可以通過(guò)在線網(wǎng)站代碼調(diào)試工具調(diào)試。 阮一峰老師開(kāi)源作品。 書上的示例代碼可以通過(guò) 在線網(wǎng)站代碼調(diào)試工具 JS Bin 調(diào)試。 作用域 作用域鏈 每個(gè)變量或函數(shù)通過(guò)執(zhí)行環(huán)境 (execution context) 定義了其有權(quán)訪問(wèn)的其他數(shù)據(jù),決定了他們各自的行為; 全局執(zhí)行環(huán)境是最頂層的執(zhí)行環(huán)境,根據(jù)宿主環(huán)境的不同,表示全局執(zhí)行環(huán)境的對(duì)象也不同:在瀏覽...

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

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

    galaxy_robot 評(píng)論0 收藏0
  • JavaScript 語(yǔ)言核心筆記(持續(xù)更新)

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

    suosuopuo 評(píng)論0 收藏0
  • [譯] ES6 學(xué)習(xí)筆記:關(guān)于 ES2015 特性的詳細(xì)概述

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

    leoperfect 評(píng)論0 收藏0
  • 【進(jìn)階1-1期】理解JavaScript 中的執(zhí)行上下文執(zhí)行

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

    import. 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<