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

資訊專欄INFORMATION COLUMN

理解作用域

gggggggbong / 741人閱讀

摘要:理解作用域,編譯器,引擎的關(guān)系用來做例子首先,編譯器遇到編譯器會詢問同一個作用域的集合中是否存在該變量。否則它會要求作用域在當(dāng)前作用域的集合中聲明一個新的變量,并命名為。但是作用域同其中的變量聲明出現(xiàn)的位置有某種微妙的關(guān)系。

作用域是什么

一套用來儲存變量的設(shè)計良好的規(guī)則,并且之后可以方便的找到這些變量。

要理解作用域,先了解一下編譯原理

分詞/詞法分析(Tokenizing/Lexing)
這個過程會將由字符組成的字符串分解成(對編程語言來說)有意義的代碼塊,這些代碼塊被稱為詞法單元(token)。例如,考慮程序var a = 2;。這段程序通常會被分解成為下面這些詞法單元:var、a、=、2 、; 空格是否會被當(dāng)作詞法單元,取決于空格在這門語言中是否具有意義。

解析/語法分析(Parsing)
這個過程是將詞法單元流(數(shù)組)轉(zhuǎn)換成一個由元素逐級嵌套所組成的代表了結(jié)構(gòu)的樹。這個樹被稱為“抽象語法樹”(Abstract Syntax Tree,AST)。

代碼生成
將AST轉(zhuǎn)換為可執(zhí)行代碼的過程稱被稱為代碼生成。這個過程與語言、目標(biāo)平臺等息息相關(guān)。拋開具體細(xì)節(jié),簡單來說就是有某種方法可以將var a = 2;的AST轉(zhuǎn)化為一組機器指令,用來創(chuàng)建一個叫作a的變量(包括分配內(nèi)存等),并將一個值儲存在a中。

理解作用域,編譯器,引擎的關(guān)系

用var a = 2;來做例子

首先,編譯器遇到var a,編譯器會詢問同一個作用域的集合中是否存在該變量。如果是,編譯器會忽略該聲明, 繼續(xù)編譯。否則它會要求作用域在當(dāng)前作用域的集合中聲明一個新的變量,并命名為a

接下來,編譯器會為引擎生成運行時所需的代碼,這些代碼被用來處理a = 2這個賦值操作。引擎運行時會首先詢問作用域,在當(dāng)前的作用域集合中是否存在一個叫作a的變量。如果是,引擎就會使用這個變量;如果否,引擎會繼續(xù)查找該變量(從作用域鏈中)。如果引擎最終找到了a變量,就會將2賦值給它。否則引擎就會舉手示意并拋出一個異常!

總結(jié):變量的賦值操作會執(zhí)行兩個動作,首先編譯器會在當(dāng)前作用域中聲明一個變量(如果之前沒有聲明過),然后在運行時引擎會在作用域中查找該變量,如果能夠找到就會對它賦值。

關(guān)于LHS和RHS

在引擎查找變量a來判斷它是否聲明過,,但是引擎執(zhí)行怎樣的查找,會影響最終的查找結(jié)果。在例子中,引擎會為變量a進(jìn)行LHS查詢。另外一個查找的類型叫作RHS。
我打賭你一定能猜到“L”和“R”的含義,它們分別代表左側(cè)和右側(cè)。
什么東西的左側(cè)和右側(cè)?是一個賦值操作的左側(cè)和右側(cè)。
換句話說,當(dāng)變量出現(xiàn)在賦值操作的左側(cè)時進(jìn)行LHS查詢,出現(xiàn)在右側(cè)時進(jìn)行RHS查詢。

總的來說如果查找的目的是對變量進(jìn)行賦值,那么就會使用LHS查詢;如果目的是獲取變量的值,就會使用RHS查詢。

作用域嵌套

作用域嵌套當(dāng)一個塊或函數(shù)嵌套在另一個塊或函數(shù)中時,就發(fā)生了作用域的嵌套。因此,在當(dāng)前作用域中無法找到某個變量時,引擎就會在外層嵌套的作用域中繼續(xù)查找,直到找到該變量,或抵達(dá)最外層的作用(也就是全局作用域)為止。
考慮以下代碼:

function foo(a) {
console.log( a + b );
}
var b = 2;
foo( 2 ); // 4

作用域共有兩種主要的工作模型。第一種是最為普遍的,被大多數(shù)編程語言所采用的詞法作用域。另外一種叫作動態(tài)作用域,仍有一些編程語言在使用(比如Bash腳本、Perl中的一些模式等)。

詞法作用域

詞法作用域就是定義在詞法階段的作用域,換句話說,詞法作用域是由你寫在代碼時將變量和代碼塊作用域?qū)懺谀睦飦頉Q定。
看下面代碼

function foo(a){
    var b = a*2;
    fucntion bar(c){
        console.log(a,b,c);
    }
    bar(b*3);
}
foo(2);//2,4,12
//這個例子中有三個助劑嵌套的作用域,其中有一個標(biāo)識符:foo
//包含著foo所創(chuàng)建的作用域,其中有三個標(biāo)識符:a, bar 和 b
//包含bar所創(chuàng)建的作用域,其中只有一個標(biāo)識符:c

作用域查找會從運行時所在時所處的最內(nèi)部作用域開始,逐級向上直到找到第一個匹配的標(biāo)識符時停止。

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

var name = "小紅";
function showName() {
    console.info(name);
}

function show() {
    var name = "小黑";
    showName();
} 
show();//小紅

如果你記住并且理解了上面的話,那么應(yīng)該可以得到這個結(jié)果。用作用域鏈的角度解析:執(zhí)行show()函數(shù)時,進(jìn)入function show(){}的作用域內(nèi),然后執(zhí)行showName()函數(shù),再進(jìn)入到function showName(){}的作用域內(nèi),要輸出name,就在當(dāng)前作用域找,但是找不到,然后就向上爬一層,在全局環(huán)境中找到了var name = "小紅";,所以show()就輸出了小紅

函數(shù)中的作用域

函數(shù)作用域的含義是指,屬于這個函數(shù)的全部變量都可以在整個函數(shù)的范圍內(nèi)使用及復(fù)用(事實上在嵌套的作用域中也可以使用)

提升

無論作用域中的聲明出現(xiàn)在什么地方,都將在代碼本身被執(zhí)行前首先進(jìn)行處理。可以將這個過程形象地想象成所有的聲明(變量和函數(shù))都會被“移動”到各自作用域的最頂端,這個過程被稱為 提升
任何聲明在某個作用域內(nèi)的變量,都將附屬于這個作用域。但是作用域同其中的變量聲明出現(xiàn)的位置有某種微妙的關(guān)系。

考慮一下代碼

a = 2
var a;
console.log(a);//2

說明先有聲明后有賦值
只有聲明本身才會被提升,而賦值或其他運行邏輯會留在原地。如果提升改變代碼的執(zhí)行順序,會造成非常嚴(yán)重的破壞。
再看個例子

foo();
function(){
    console.log(a);//undefined
    var a = 2;
}
 //foo函數(shù)的聲明被提升了,因此函數(shù)第一行中的調(diào)用可以正常執(zhí)行,函數(shù)內(nèi)部對var a進(jìn)行提升。因此上面的代碼會被理解成下面的形式。

function foo(){
    var a;
    console.log(a);
    a = 2;
}
foo();
函數(shù)優(yōu)先

函數(shù)聲明和變量聲明都會被提升。但首先是被提升,然后才是變量。
考慮如下代碼

foo()
var foo;
function foo(){
    console.log(1);
}
foo = function(){
    console.log(2);
};
//會輸出1而不是2,這個代碼片段會被解釋成

function foo(){
    console.log(1);
}
foo();//1
foo = function(){
    console.log(2);
}

//出現(xiàn)在后面的函數(shù)聲明還是可以覆蓋前面的
foo();//3
function foo(){
    console.log(1);
}
var foo = function(){
    console.log(2);
}
function foo(){
    console.log(3);
}

最后要注意避免重復(fù)聲明,特別是當(dāng)普通的var聲明和函數(shù)聲明混合在一起的時候,否則會出現(xiàn)問題

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80908.html

相關(guān)文章

  • 深入理解JavaScript作用作用

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...

    baiy 評論0 收藏0
  • 深入理解JavaScript作用作用

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...

    ytwman 評論0 收藏0
  • Js基礎(chǔ)知識(三) - 作用與閉包

    摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級作用域。 作用域與閉包 如何用js創(chuàng)建10個button標(biāo)簽,點擊每個按鈕時打印按鈕對應(yīng)的序號? 看到上述問題,如果你能看出來這個問題實質(zhì)上是考對作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...

    lemanli 評論0 收藏0
  • Js基礎(chǔ)知識(三) - 作用與閉包

    摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級作用域。 作用域與閉包 如何用js創(chuàng)建10個button標(biāo)簽,點擊每個按鈕時打印按鈕對應(yīng)的序號? 看到上述問題,如果你能看出來這個問題實質(zhì)上是考對作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...

    XFLY 評論0 收藏0
  • Js基礎(chǔ)知識(三) - 作用與閉包

    摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級作用域。 作用域與閉包 如何用js創(chuàng)建10個button標(biāo)簽,點擊每個按鈕時打印按鈕對應(yīng)的序號? 看到上述問題,如果你能看出來這個問題實質(zhì)上是考對作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...

    tanglijun 評論0 收藏0

發(fā)表評論

0條評論

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