變量的作用域
- 在js中我們把作用域分為全局作用域和局部作用域,全局作用域就是window,在沒 有塊級作用域概念的時候,每一個函數(shù)都是一個局部作用域。
- 其實變量的作用域,就說指變量的有效范圍。我們最長說的就是在函數(shù)中聲明的變 量作用域。
- 當在函數(shù)中聲明一個變量的時候,如果改變量沒有用var關鍵字去定義那么該變量就 是一個全局變量,但是這樣做最容易造成命名沖突。
- 另一種情況就是使用var聲明的變量,這時候的變量就是局部變量,只有在該函數(shù)內 部可以訪問,在函數(shù)外面是訪問不到的
- 在javascript中,函數(shù)可以用來創(chuàng)造函數(shù)作用域。在函數(shù)中搜索變量的時候,如果該 函數(shù)當中沒有這個變量,那么這次搜索過程會隨著代碼執(zhí)行環(huán)境創(chuàng)建的作用域 鏈往外層逐層搜索,一直搜索到window對象為止,找不到就會拋出一個為定義 的錯誤。而這種從內到外逐層查找的關系在js中我們稱為作用域鏈
let,const,var的區(qū)別與聯(lián)系
- 在javascript中我們通常使用var會發(fā)生變量提升,即腳本開始運行時,變量已經存在了,但是沒有值,所以會輸出undefined而let不會發(fā)生變量提升,這表示在聲明它之前,變量是不存在的,這時如果用到它,就會拋出一個錯誤。
- var 是函數(shù)級作用域,let是塊級作用域:
{
let a = 10;
var b = 1;
}
a // ReferenceError:a is not defined.
b // 1
容易發(fā)生錯誤:
var a = [];
for(var i = 0; i < 10; i++){
a[i] = function(){
console.log(i);
};
}
a[6](); // 10;
如果將var i 改為 let i 此時a[6](); 結果是6;
- let不允許在相同作用域內,重復聲明同一個變量:
function(){
let a = 10;
var a = 1;
}
//報錯
function(){
let a = 10;
let a = 1;
}
//報錯
- const聲明一個只讀的常量。一旦聲明,常量的值就不能改變
const PI = 3.1415;
PI = 3;
//TypeError: Assignment to constant variable.
- const命令聲明的常量也是不提升,只能在聲明的位置后面使用。
{
const a = 10;
}
console.log(a);
//報錯
- const聲明的常量,也與let一樣不可重復聲明
- 對于復合類型的變量,變量名不指向數(shù)據(jù),而是指向數(shù)據(jù)所在的地址。const命令只是保證變量名指向的地址不變,并不保證該地址的數(shù)據(jù)不變,所以將一個對象聲明為常量必須非常小心。
const t = {};
t.prop = 123;
console.log(t.prop); // 123
t = {}; // 報錯
變量的生存周期
除了變量作用域之外,另外一個跟閉包有關的概念就是變量的生存周期,對于全局變 量來說,全局變量的生存周期是永久的,除非我們主動銷毀這個全局變量,而對于函 數(shù)內部的使用var聲明的變量來說,當退出函數(shù)是,這些變量就會隨著函數(shù)的結束而銷 毀。