Javascript執(zhí)行上下文、this、作用域

前置:重要事情說(shuō)三遍:執(zhí)行上下文和作用域不一樣!不一樣!不一樣!

1、執(zhí)行上下文和作用域之間最大的區(qū)別是:

執(zhí)行上下文在運(yùn)行時(shí)確定,隨時(shí)可能改變;作用域在定義時(shí)確定,永遠(yuǎn)不會(huì)改變。

2、每個(gè)執(zhí)行上下文都有三個(gè)重要的屬性,變量對(duì)象(Variable object,VO),作用域鏈(Scope chain)和this,當(dāng)然還有一些附加的屬性。

實(shí)例、

? ?var a=1;//全局作用域? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? ?function fn1(){

? ?var a=2; //fn1作用域

? ? }

?this.a=1;//全局執(zhí)行上下文 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?function fn1(){

this.a=2; //fn1執(zhí)行上下文

}

var obj=new fn1();


一、執(zhí)行上下文

綜述:每次當(dāng)控制器轉(zhuǎn)到可執(zhí)行代碼的時(shí)候,就會(huì)進(jìn)入一個(gè)執(zhí)行上下文。執(zhí)行上下文可以理解為當(dāng)前代碼的執(zhí)行環(huán)境,它會(huì)形成一個(gè)作用域。JavaScript中的運(yùn)行環(huán)境大概包括三種情況。

1、全局環(huán)境:JavaScript代碼運(yùn)行起來(lái)會(huì)首先進(jìn)入該環(huán)境

2、函數(shù)環(huán)境:當(dāng)函數(shù)被調(diào)用執(zhí)行時(shí),會(huì)進(jìn)入當(dāng)前函數(shù)中執(zhí)行代碼

3、eval

在一個(gè)JavaScript程序中,必定會(huì)產(chǎn)生多個(gè)執(zhí)行上下文,JavaScript引擎會(huì)以堆棧的方式來(lái)處理它們。棧永遠(yuǎn)都是全局上下文,而棧就是當(dāng)前正在執(zhí)行的上下文。

當(dāng)代碼在執(zhí)行過(guò)程中,遇到以上三種情況,都會(huì)生成一個(gè)執(zhí)行上下文,放入棧中,而處于棧頂?shù)纳舷挛膱?zhí)行完畢之后,就會(huì)自動(dòng)出棧。

(1)變量對(duì)象VO和活動(dòng)對(duì)象AO

變量對(duì)象VO是與執(zhí)行上下文相關(guān)的特殊對(duì)象,用來(lái)存儲(chǔ)上下文的函數(shù)聲明,函數(shù)形參和變量。在global全局上下文中,變量對(duì)象也是全局對(duì)象自身;在函數(shù)執(zhí)行上下文中,VO是不能直接訪問(wèn)的,此時(shí)由活動(dòng)對(duì)象(activation object,縮寫(xiě)為AO)扮演VO的角色。

變量對(duì)象VO存儲(chǔ)上下文中聲明的以下內(nèi)容

{

}

二、this

this代表了當(dāng)前對(duì)象的一個(gè)引用。

1、this指代全局

var name ="global this";

functionglobalTest() {

console.log(this.name);?

?}?

?globalTest();//global this

2、this指代構(gòu)造函數(shù)

var name ="global name";

function showName() {? ?//構(gòu)造函數(shù)

this.name ="showName function";?

?}

var obj =new showName();

console.log(obj.name);? //showName?

functionconsole.log(name);? //global name

3、指向某個(gè)對(duì)象

如果函數(shù)作為對(duì)象的方法調(diào)用,this指向的是這個(gè)上級(jí)對(duì)象,即調(diào)用方法的對(duì)象

function? showName() {? ?//普通函數(shù)

console.log(this.name);?

?}

var obj = {};?

?obj.name ="ooo";?

?obj.show = showName;?

?obj.show();? //ooo

4、apply/call調(diào)用時(shí)的this

apply和call都是為了改變函數(shù)體內(nèi)部的this指向。

call(thisObj,Object)? ?;apply(thisObj,[argArray])

var value ="Global value";

functionFunA() {

this.value ="AAA";?

?}

functionFunB()?{

console.log(this.value);

?}?

?FunB();? ? ? ? ?//Global value 因?yàn)槭窃谌种姓{(diào)用的FunB(),this.value指向全局的value FunB.call(window);? ? ? ? //Global value,this指向window對(duì)象,因此this.value指向全局的value FunB.call(new FunA());? ? ? ? ?//AAA, this指向參數(shù)new FunA(),即FunA對(duì)象 FunB.apply(window);? ? ? ? ? ?//Global value FunB.apply(new FunA());//AAA

三、作用域

首先,js只有函數(shù)作用域(function-based),沒(méi)有塊級(jí)作用域,也就是只有函數(shù)會(huì)有自己的作用域,其他都沒(méi)有。

接著,作用域分為全局作用域與局部作用域。

全局作用域中的對(duì)象可以在代碼的任何地方訪問(wèn),一般來(lái)說(shuō),下面情況的對(duì)象會(huì)在全局作用域中:

最外層函數(shù)和在最外層函數(shù)外面定義的變量

沒(méi)有通過(guò)關(guān)鍵字"var"聲明的變量

瀏覽器中,window對(duì)象的屬性

局部作用域又被稱(chēng)為函數(shù)作用域(Function scope),所有的變量和函數(shù)只能在作用域內(nèi)部使用。


參考:https://www.cnblogs.com/nanchen/p/6055016.html

? ? ? ? ? https://www.cnblogs.com/lsgxeva/p/7975669.html

? ? ? ? ? http://www.itdecent.cn/p/edb2be5866eb

? ? ? ? ?https://blog.csdn.net/github_34514750/article/details/52901781

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容