前置:重要事情說三遍:執(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)行起來會(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ì)以堆棧的方式來處理它們膊爪。棧底永遠(yuǎn)都是全局上下文自阱,而棧頂就是當(dāng)前正在執(zhí)行的上下文。
當(dāng)代碼在執(zhí)行過程中米酬,遇到以上三種情況沛豌,都會(huì)生成一個(gè)執(zhí)行上下文,放入棧中赃额,而處于棧頂?shù)纳舷挛膱?zhí)行完畢之后加派,就會(huì)自動(dòng)出棧。
(1)變量對(duì)象VO和活動(dòng)對(duì)象AO
變量對(duì)象VO是與執(zhí)行上下文相關(guān)的特殊對(duì)象,用來存儲(chǔ)上下文的函數(shù)聲明爬早,函數(shù)形參和變量哼丈。在global全局上下文中,變量對(duì)象也是全局對(duì)象自身筛严;在函數(shù)執(zhí)行上下文中媒咳,VO是不能直接訪問的六水,此時(shí)由活動(dòng)對(duì)象(activation object,縮寫為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),沒有塊級(jí)作用域肖抱,也就是只有函數(shù)會(huì)有自己的作用域备典,其他都沒有。
接著虐沥,作用域分為全局作用域與局部作用域熊经。
全局作用域中的對(duì)象可以在代碼的任何地方訪問泽艘,一般來說欲险,下面情況的對(duì)象會(huì)在全局作用域中:
最外層函數(shù)和在最外層函數(shù)外面定義的變量
沒有通過關(guān)鍵字"var"聲明的變量
瀏覽器中镐依,window對(duì)象的屬性
局部作用域又被稱為函數(shù)作用域(Function scope),所有的變量和函數(shù)只能在作用域內(nèi)部使用天试。
參考:https://www.cnblogs.com/nanchen/p/6055016.html
? ? ? ? ? https://www.cnblogs.com/lsgxeva/p/7975669.html
? ? ? ? ? http://www.reibang.com/p/edb2be5866eb
? ? ? ? ?https://blog.csdn.net/github_34514750/article/details/52901781