九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
深入理解javascript作用域系列第二篇

深入理解javascript作用域系列第二篇——詞法作用域和動(dòng)態(tài)作用域

前面的話

  大多數(shù)時(shí)候,我們對(duì)作用域產(chǎn)生混亂的主要原因是分不清楚應(yīng)該按照函數(shù)位置的嵌套順序,還是按照函數(shù)的調(diào)用順序進(jìn)行變量查找。再加上this機(jī)制的干擾,使得變量查找極易出錯(cuò)。這實(shí)際上是由兩種作用域工作模型導(dǎo)致的,作用域分為詞法作用域和動(dòng)態(tài)作用域,分清這兩種作用域模型就能夠?qū)ψ兞坎檎疫^(guò)程有清晰的認(rèn)識(shí)。本文是深入理解javascript作用域系列第二篇——詞法作用域和動(dòng)態(tài)作用域

 

詞法作用域

  第一篇介紹過(guò),編譯器的第一個(gè)工作階段叫作分詞,就是把由字符組成的字符串分解成詞法單元。這個(gè)概念是理解詞法作用域的基礎(chǔ)

  簡(jiǎn)單地說(shuō),詞法作用域就是定義在詞法階段的作用域,是由寫代碼時(shí)將變量和塊作用域?qū)懺谀睦飦?lái)決定的,因此當(dāng)詞法分析器處理代碼時(shí)會(huì)保持作用域不變

關(guān)系

  無(wú)論函數(shù)在哪里被調(diào)用,也無(wú)論它如何被調(diào)用,它的詞法作用域都只由函數(shù)被聲明時(shí)所處的位置決定

function foo(a) {    var b = a * 2;    function bar(c) {        console.log( a, b, c );    }    bar(b * 3);}foo( 2 ); // 2 4 12

  在這個(gè)例子中有三個(gè)逐級(jí)嵌套的作用域。為了幫助理解,可以將它們想象成幾個(gè)逐級(jí)包含的氣泡

  作用域氣泡由其對(duì)應(yīng)的作用域塊代碼寫在哪里決定,它們是逐級(jí)包含的

  氣泡1包含著整個(gè)全局作用域,其中只有一個(gè)標(biāo)識(shí)符:foo

  氣泡2包含著foo所創(chuàng)建的作用域,其中有三個(gè)標(biāo)識(shí)符:a、bar和b

  氣泡3包含著bar所創(chuàng)建的作用域,其中只有一個(gè)標(biāo)識(shí)符:c

查找

  作用域氣泡的結(jié)構(gòu)和互相之間的位置關(guān)系給引擎提供了足夠的位置信息,引擎用這些信息來(lái)查找標(biāo)識(shí)符的位置

  在代碼片段中,引擎執(zhí)行console.log(...)聲明,并查找a、b和c三個(gè)變量的引用。它首先從最內(nèi)部的作用域,也就是bar(...)函數(shù)的作用域開(kāi)始查找。引擎無(wú)法在這里找到a,因此會(huì)去上一級(jí)到所嵌套的foo(...)的作用域中繼續(xù)查找。在這里找到了a,因此引擎使用了這個(gè)引用。對(duì)b來(lái)講也一樣。而對(duì)c來(lái)說(shuō),引擎在bar(...)中找到了它

  [注意]詞法作用域查找只會(huì)查找一級(jí)標(biāo)識(shí)符,如果代碼引用了foo.bar.baz,詞法作用域查找只會(huì)試圖查找foo標(biāo)識(shí)符,找到這個(gè)變量后,對(duì)象屬性訪問(wèn)規(guī)則分別接管對(duì)bar和baz屬性的訪問(wèn)

foo = {    bar:{        baz: 1    }};console.log(foo.bar.baz);//1

遮蔽

  作用域查找從運(yùn)行時(shí)所處的最內(nèi)部作用域開(kāi)始,逐級(jí)向外或者說(shuō)向上進(jìn)行,直到遇見(jiàn)第一個(gè)匹配的標(biāo)識(shí)符為止

  在多層的嵌套作用域中可以定義同名的標(biāo)識(shí)符,這叫作“遮蔽效應(yīng)”,內(nèi)部的標(biāo)識(shí)符“遮蔽”了外部的標(biāo)識(shí)符

var a = 0;function test(){    var a = 1;    console.log(a);//1}test();

  全局變量會(huì)自動(dòng)為全局對(duì)象的屬性,因此可以不直接通過(guò)全局對(duì)象的詞法名稱,而是間接地通過(guò)對(duì)全局對(duì)象屬性的引用來(lái)對(duì)其進(jìn)行訪問(wèn)

var a = 0;function test(){    var a = 1;    console.log(window.a);//0}test();

  通過(guò)這種技術(shù)可以訪問(wèn)那些被同名變量所遮蔽的全局變量。但非全局的變量如果被遮蔽了,無(wú)論如何都無(wú)法被訪問(wèn)到

 

動(dòng)態(tài)作用域

  javascript使用的是詞法作用域,它的最重要的特征是它的定義過(guò)程發(fā)生在代碼的書(shū)寫階段

  那為什么要介紹動(dòng)態(tài)作用域呢?實(shí)際上動(dòng)態(tài)作用域是javascript另一個(gè)重要機(jī)制this的表親。作用域混亂多數(shù)是因?yàn)樵~法作用域和this機(jī)制相混淆,傻傻分不清楚

  動(dòng)態(tài)作用域并不關(guān)心函數(shù)和作用域是如何聲明以及在任何處聲明的,只關(guān)心它們從何處調(diào)用。換句話說(shuō),作用域鏈?zhǔn)腔谡{(diào)用棧的,而不是代碼中的作用域嵌套

var a = 2;function foo() {    console.log( a );}function bar() {    var a = 3;    foo();}bar();

  【1】如果處于詞法作用域,也就是現(xiàn)在的javascript環(huán)境。變量a首先在foo()函數(shù)中查找,沒(méi)有找到。于是順著作用域鏈到全局作用域中查找,找到并賦值為2。所以控制臺(tái)輸出2

  【2】如果處于動(dòng)態(tài)作用域,同樣地,變量a首先在foo()中查找,沒(méi)有找到。這里會(huì)順著調(diào)用棧在調(diào)用foo()函數(shù)的地方,也就是bar()函數(shù)中查找,找到并賦值為3。所以控制臺(tái)輸出3

  兩種作用域的區(qū)別,簡(jiǎn)而言之,詞法作用域是在定義時(shí)確定的,而動(dòng)態(tài)作用域是在運(yùn)行時(shí)確定的

好的代碼像粥一樣,都是用時(shí)間熬出來(lái)的
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
作用域和閉包
(12) javascript中var、let、const聲明的區(qū)別
什么是JavaScript的作用域
手把手教會(huì)你JavaScript引擎如何執(zhí)行JavaScript代碼
深入理解JavaScript系列(14):作用域鏈(Scope Chain)
理解 JavaScript 作用域
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服