對作用域的理解

全局作用域

在全局作用域中定義的變量,在整個上下文中都是可以訪問的。

函數作用域

在函數作用域中定義的變量,只能在函數中被訪問

作用域鏈

//全局環境下的全局變量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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章