全局作用域
在全局作用域中定義的變量,在整個上下文中都是可以訪問的。
函數作用域
在函數作用域中定義的變量,只能在函數中被訪問
作用域鏈
//全局環境下的全局變量a1
var a1 = 5;
//全局環境下的方法funcName1
function funcName1(){
//funcName1方法作用域下的局部變量a2
var a2 = 10;
//funcName1方法作用域下的方法funcName2
function funcName2(){
//當前環境funcName2中沒有a1->父環境funcName1沒有a1->全局環境發現a1
console.log(a1);//5
//當前環境funcName2中沒有a2->父環境funcName1發現a2
console.log(a2);//10
//funcName2方法作用域下的局部變量tempNum
var tempNum;
//交換a1和a2
tempNum = a1;
a2 = a1;
a51 = tempNum;
//當前環境funcName2中沒有a1->父環境funcName1沒有a1->全局環境發現a1
console.log(a1);//10
//當前環境funcName2中沒有a2->父環境funcName1發現a2
console.log(a2);//5
//當前環境funcName2中發現tempNum
console.log(tempNum);//5
}
//運行funcName1方法作用域下的方法funcName2
funcName2();
//當前環境funcName1沒有a1->全局環境發現a1
console.log(a1);//10
//當前環境funcName1發現a2
console.log(a2);//5
//因爲tempNum在當前環境funcName1的子環境下,所以查不到
//console.log(tempNum);拋出錯誤:Uncaught ReferenceError: tempNum is not defined
}
//運行全局環境下的方法funcName1
funcName1();
//全局環境下的變量a1
console.log(a1);//10
//因爲a2在當前全局環境的子環境下,所以查不到
// console.log(a2);//拋出錯誤:Uncaught ReferenceError: a2 is not defined
變量提升
函數及變量的聲明都將被提升到函數的最頂部。
//首先
var x; // 這是一個 被聲明但未被初始化 的變量,值爲undefined
var y = 10; //這是一個 被聲明+被初始化 的變量,值爲10
//a3未被聲明,所以報錯
//console.log(a3);Uncaught ReferenceError: a3 is not defined
//a4的聲明被提升到最頂部,但是初始化沒法提升,所以打印出的a4是個被聲明但是未被初始化的變量
console.log(a4);//undefined
var a4;
var a5=10;
function funcName3(){
//在funcName3環境下,由於變量提升,a5在funcName3環境下的聲明被提升到了funcName3環境的最頂部,初始化沒法提升。
console.log(a5);//undefined
var a5=5;
}
funcName3();
//funcName3環境下的a5不是全局變量a5。
console.log(a5);//10
函數提升
函數的聲明方式決定是否能被提升
function funcName4(){
testFunc();
function testFunc(){
console.log("可以被提升");
}
}
funcName4();
function funcName5(){
testFunc();
//函數聲明法可以被提升
var func = testFunc(){
console.log("不可以被提升");
}
}
funcName5();
塊級作用域
概念“{}”中間的部分都是塊級作用域,如for、while、if 。
let 與 var 的探究
全局作用域下
// 結論: 在全局作用域中let不能重新聲明var聲明過的變量
// var x = 1;
// let x = 2;//Uncaught SyntaxError: Identifier 'x' has already been declared
// 結論: 在全局作用域中var不能重新聲明let聲明過的變量
// let x = 1;
// var x = 2;//Uncaught SyntaxError: Identifier 'x' has already been declared
// 結論: 在全局作用域中let不能重新聲明let聲明過的變量
// let x = 1;
// let x = 2;//Uncaught SyntaxError: Identifier 'x' has already been declared
// 結論: 在全局作用域中var可以重新聲明var聲明過的變量
var x = 1;
var x = 2;
在不同作用域內
// 結論: 在不同作用域內,let聲明的都是在當前作用域的對象。
let x = 1;
console.log(x);//1
{
let x = 2;
console.log(x);//2
}
{
let x = 3;
console.log(x);//3
}
console.log(x);//1
// 結論: var可以忽視塊級作用域,當做塊級不存在就好
console.log(x);//undefined 變量提升
{
var x = 1;
console.log(x);//1
}
{
var x = 2;
console.log(x);//2
}
console.log(x);//2