執(zhí)行環(huán)境以及作用域
這一塊的內(nèi)容亏娜,其實(shí)在挺多面試的時(shí)候會(huì)有問薇溃,所以我打算好好總結(jié)一下
- 執(zhí)行環(huán)境也叫環(huán)境章喉,它定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為
- 執(zhí)行環(huán)境分為全局執(zhí)行環(huán)境和局部執(zhí)行環(huán)境
1.對(duì)于全局執(zhí)行環(huán)境來說男翰,你可以把它理解為最外邊的一個(gè)執(zhí)行環(huán)境另患,在web瀏覽器中,全局執(zhí)行環(huán)境可以認(rèn)為是 windows 對(duì)象,因?yàn)?window 對(duì)象屬性和方法往往可以用來創(chuàng)建全局變量和函數(shù)
2.局部執(zhí)行環(huán)境蛾绎,則是在全局作用域內(nèi)的執(zhí)行環(huán)境 - 作用域昆箕,在執(zhí)行環(huán)境中,里邊的代碼在執(zhí)行的時(shí)候會(huì)生成一個(gè)作用域鏈租冠,他的作用鹏倘,除了對(duì)代碼設(shè)置了訪問權(quán)限之外,同時(shí)還保證了代碼的有序訪問
關(guān)于權(quán)限的解釋
1.如上圖所示顽爹,在全局執(zhí)行環(huán)境A中有一個(gè)變量a纤泵,在全局環(huán)境A下有一個(gè)局部執(zhí)行環(huán)境B,B中也有一個(gè)變量b镜粤,在環(huán)境B下任然有一個(gè)局部環(huán)境C捏题,環(huán)境C中有一個(gè)變量c。 *
2.變量c只能在環(huán)境C里邊才能訪問肉渴,變量a和變量b都無權(quán)訪問公荧,但是變量c可以訪問環(huán)境A,B中的變量,同理在環(huán)境B中同规,變量b雖然不能訪問變量c循狰,但是卻可以訪問變量a。原因就是環(huán)境A是環(huán)境B的父環(huán)境券勺,而環(huán)境B又是環(huán)境C的父環(huán)境*
var a = "a";
function B() {
var b = "b";
function C() {
var c = b;
b = a;
a = c;
document.write(a); //b
document.write(b); //a
document.write(c + "</br>"); //b
}
C();
document.write(a); //b
document.write(b); //a
}
B();
延長作用域鏈
在 JavaScript 中是有個(gè)別語句可以用來延長作用域的绪钥,比如** try-catch 語句中的catch 塊 ,with語句**
function a() {
var bk = "?debug=true";
with(location){
var url = href + bk;
}
alert(url); //這里輸出的就是當(dāng)前的地址关炼,還有qs的值
}
沒有塊級(jí)的作用域
在 JavaScript 中如果沒有塊作用域程腹,經(jīng)常會(huì)出現(xiàn)一些很奇怪的錯(cuò)誤
<!-- 在 JavaScript 中 if 語句與 for 循環(huán)語句有些不一樣-->
if(true){
var a = 1;
}
alert(a);
function a() {
for(var i = 0; i < 5; i++){
}
alert(i);
}
a();
在同一個(gè)作用域中,if 與 for 中的變量在當(dāng)前作用域里邊執(zhí)行完畢之后儒拂,不會(huì)被銷毀跪楞,而是被保存在距離它最近的執(zhí)行環(huán)境里
1.變量聲明
//在 JavaScript 中在作用域里邊如果沒有用 var 聲明變量缀去,
//那么將會(huì)被當(dāng)成全局變量
function test(a , b){
var sum = a + b;
return sum;
}
test(1 , 2);
alert (sum); //瀏覽器會(huì)報(bào)錯(cuò)
但是甸祭,如果把 var 去掉,那么結(jié)果就不一樣了
function test(a , b){
sum = a + b褥影;
return sum;
}
test(1 , 2);
alert (sum); //輸出 3
2.查詢標(biāo)識(shí)符
在 JavaScript 中池户,如果引用了一個(gè)變量,首先會(huì)在當(dāng)前函數(shù)中查找凡怎,如果沒有找到校焦,就會(huì)往上一級(jí)的環(huán)境變量中去查找
var a = 0;
function b() {
//var a = 1; 如果加上這一條命令,那么輸出就變成 1
var c = 3;
return a; //a在 b() 中沒有被找到统倒,就會(huì)去全局變量找
}
alert(b()); //輸出0;
JavaScript 垃圾清理方式
在 JavaScript 中寨典,垃圾清理的方式主要有兩種
- 標(biāo)記清除
- 引用計(jì)數(shù)
1.標(biāo)記清除
在 JavaScript 中,每當(dāng)聲明一個(gè)變量時(shí)房匆,都會(huì)對(duì)其進(jìn)行標(biāo)記耸成,對(duì)于那些不再使用的變量,JavaScript 將會(huì)將標(biāo)記改成"不再使用浴鸿,或者離開環(huán)境"的標(biāo)記井氢,對(duì)其刪除。
2.引用計(jì)數(shù)
*在 JavaScript 中岳链,所有的變量花竞,在被調(diào)用一次,就會(huì)對(duì)它進(jìn)行加一的操作掸哑,意思就是說约急,第一次調(diào)用會(huì)被記為 1 ,如果再次被調(diào)用苗分,就變成 2厌蔽。反之,如果引用這個(gè)變量的變量有引用了其他的值俭嘁,那么之前那個(gè)變量就會(huì)減一躺枕,最后變?yōu)?0 就會(huì)被刪除。 *
JavaScript 內(nèi)存管理
function a(num) {
var localnum = new Object();
localnum.num = num;
return localnum;
}
var globlenum = a(1);
globlenum = null;
在這串代碼中供填,我們將 a(1) 的值賦給 globlenum 拐云,在 a() 中,當(dāng)執(zhí)行完 return 之后近她,局部變量的值就會(huì)被清空叉瘩,但是對(duì)于已經(jīng)得到 a(1) 值的全局變量 globlenum 來說,它的值會(huì)被一直保存下來粘捎,因此我們需要改變它的值 薇缅,人為的將它的計(jì)數(shù)減一危彩,方便垃圾收集器回收。