javascript
1月8日学习内容整理:JS的作用域和作用域链
補(bǔ)充:
對(duì)于編譯型語(yǔ)言,是編譯一次生成可執(zhí)行文件來(lái)執(zhí)行多次;對(duì)于解釋型語(yǔ)言,始終都是編譯一次執(zhí)行一次
python編譯時(shí)要看有沒(méi)有賦值操作,沒(méi)有的話就不編譯任何內(nèi)容;若有賦值操作,才會(huì)開(kāi)辟內(nèi)存空間,把變量指向這個(gè)內(nèi)存空間,python執(zhí)行時(shí)才會(huì)真正完成賦值操作,將這個(gè)值存放在編譯時(shí)開(kāi)辟的內(nèi)存地址空間里,變量指向這個(gè)地址空間,這就完成了一次賦值的編譯執(zhí)行操作
這里所說(shuō)的變量也包括函數(shù)名,對(duì)于定義函數(shù),js編譯時(shí)會(huì)把名字直接指向function的地址,
?
作用域就是變量與函數(shù)的可訪問(wèn)范圍,即作用域控制著變量與函數(shù)的可見(jiàn)性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。
?
一、全局作用域
1、在代碼中任何地方都能訪問(wèn)到的對(duì)象擁有全局作用域,一般來(lái)說(shuō)一下幾種情形擁有全局作用域:
其實(shí)js的作用域和python的基本相同,我們可以按照python作用域?qū)s變量進(jìn)行分析,但要注意if 和 ?for沒(méi)有自己的作用域,
var ?x ?這只是聲明變量,編譯時(shí)也開(kāi)辟內(nèi)存空間,執(zhí)行時(shí)js會(huì)默認(rèn)把值設(shè)為undefined,若是python的話執(zhí)行時(shí)就直接報(bào)錯(cuò)了,因?yàn)榫幾g時(shí)沒(méi)有賦值操作也就不會(huì)開(kāi)辟內(nèi)存空間
var ?x=10 ? 這是既聲明又賦值,并且要注意的是下面的第2點(diǎn),沒(méi)有var聲明的變量js會(huì)自動(dòng)設(shè)置為全局變量
(1)最外層函數(shù)和在最外層函數(shù)外面定義的變量擁有全局作用域
var name="yuan";function foo(){var age=23;function inner(){console.log(age);}inner();}console.log(name); // yuan//console.log(age); // Uncaught ReferenceError: age is not definedfoo(); // 23inner(); // Uncaught ReferenceError: inner is not defined?
(2)所有末定義直接賦值的變量自動(dòng)聲明為擁有全局作用域,例如:
var name="yuan";function foo(){age=23;var sex="male"}foo();console.log(age); // 23console.log(sex); // sex is not defined?
(3)所有window對(duì)象的屬性擁有全局作用域
一般情況下,window對(duì)象的內(nèi)置屬性都都擁有全局作用域,例如window.alert()、window.location、window.top等等。
?
二、局部作用域
和全局作用域相反,局部作用域一般只在固定的代碼片段內(nèi)可訪問(wèn)到,最常見(jiàn)的例如函數(shù)內(nèi)部,所有在一些地方也會(huì)看到有人把這種作用域成為函數(shù)作用域.
?
三、作用域鏈
在JavaScript中,函數(shù)也是對(duì)象,實(shí)際上,JavaScript里一切都是對(duì)象。函數(shù)對(duì)象和其它對(duì)象一樣,擁有可以通過(guò)代碼訪問(wèn)的屬性和一系列僅供JavaScript引擎訪問(wèn)的內(nèi)部屬性。其中一個(gè)內(nèi)部屬性是[[Scope]],由ECMA-262標(biāo)準(zhǔn)第三版定義,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合,這個(gè)集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問(wèn)。
//-----**********************例1*********************************var s=12;function f(){console.log(s);var s=12; // if s=12 console.log(s)}f();//-----**********************例2*********************************var s=10; function foo(){console.log(s);var s=5;console.log(s);function s(){console.log("ok")}// 函數(shù)的定于或聲明是在詞法分析時(shí)完成的,執(zhí)行時(shí)已不再有任何操作 console.log(s); }foo();//-----***********************例3********************************function bar(age) {console.log(age);var age = 99;var sex= 'male';console.log(age);function age() {alert(123)};console.log(age);return 100; }result=bar(5);//-----********************************************************?
以例3為例:
當(dāng)一個(gè)函數(shù)創(chuàng)建后,它的作用域鏈會(huì)被創(chuàng)建此函數(shù)的作用域中可訪問(wèn)的數(shù)據(jù)對(duì)象填充。在函數(shù)bar創(chuàng)建時(shí),它的作用域鏈中會(huì)填入一個(gè)全局對(duì)象,該全局對(duì)象包含了所有全局變量,如下圖所示:
?
解析到函數(shù)調(diào)用時(shí),即bar(5),會(huì)生成一個(gè)active object的對(duì)象,該對(duì)象包含了函數(shù)的所有局部變量、命名參數(shù)、參數(shù)集合以及this,然后此對(duì)象會(huì)被推入作用域鏈的前端,當(dāng)運(yùn)行期上下文被銷毀,活動(dòng)對(duì)象也隨之銷毀。新的作用域鏈如下圖所示:
?
?過(guò)程解析:
function bar(age) {console.log(age);var age = 99;var sex="male";console.log(age);function age(){alert(123);} ;console.log(age);return 100; }result=bar(5);一 詞法分析過(guò)程(涉及參數(shù),局部變量聲明,函數(shù)聲明表達(dá)式):1-1 、分析參數(shù),有一個(gè)參數(shù),形成一個(gè) AO.age=undefine;1-2 、接收參數(shù) AO.age=5;1-3 、分析變量聲明,有一個(gè) var age, 發(fā)現(xiàn) AO 上面有一個(gè) AO.age ,則不做任何處理1-4 、分析變量聲明,有一個(gè) var sex,形成一個(gè) AO.sex=undefine;1-5 、分析函數(shù)聲明,有一個(gè) function age(){} 聲明, 則把原有的 age 覆蓋成 AO.age=function(){}; 二 執(zhí)行過(guò)程:2-1 、執(zhí)行第一個(gè) console.log(age) 時(shí),當(dāng)前的 AO.age 是一個(gè)函數(shù),所以輸出的一個(gè)函數(shù)2-2 、這句 var age=99; 是對(duì)不 AO.age 的屬性賦值, AO.age=99 ,所以在第二個(gè)輸出的age是 99;2-3 、同理第三個(gè)輸出的是 99, 因?yàn)橹虚g沒(méi)有改變 age 值的語(yǔ)句了。注意:執(zhí)行階段:function age(){alert(123)} ;不進(jìn)行任何操作,將執(zhí)行語(yǔ)句復(fù)制給age這部操作是在詞法分析時(shí),即運(yùn)行前完成的。?
轉(zhuǎn)載于:https://www.cnblogs.com/wanghl1011/articles/8242956.html
總結(jié)
以上是生活随笔為你收集整理的1月8日学习内容整理:JS的作用域和作用域链的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Regex pattern in ope
- 下一篇: java8 parallelStream