JavaScript的做用域

做用域

變量和函數都有做用域,做用域就是變量和函數可被訪問的範圍,控制着變量和函數的可見性和生命週期(生命週期指一個事物開始到結束中間那一段時間)
變量的做用域可被分爲全局做用域和局部做用域(函數做用域),若是變量是被定義在全局做用域的話,在JavaScript代碼中的任何位置均可以訪問該變量;若是變量被定義在指定函數內部,在JavaScript代碼中只能在該函數內部訪問該變量。
函數的做用域也可被分爲全局做用域和局部做用域(函數做用域),被定義在指定函數內部的函數被稱爲局部函數或內部函數。java

全局變量

全部函數以外聲明的變量,叫全局變量,它可被當前文檔中的其餘代碼所訪問web

//第一種定義全局變量的方式:
var str='hello web';//定義全局變量str
//在全局做用域訪問全局變量str
//輸出結果:字符串的hello web
console.log(str);
function fun(){
//在函數做用域訪問全局變量str
//輸出結果:字符串的hell web
    console.log(str);
}
//調用fun
fun();

//第二種定義全局變量的方式:
function fn(){
    /*定義變量時沒有用var關鍵字,這時的變量時全局的,
    只要沒用var聲明的默認爲全局變量*/
    str1='this is javaScript';
    //輸出結果:字符串 this is javaScript
    console.log(str1);
}
fn();
/*在全局做用域訪問變量str1,此時一樣能夠訪問到,雖然是定義在函數內部,
可是它並無用var關鍵字*/
console.log(str1);//輸出結果字符串this is javaScript

局部變量

在函數內部聲明的變量,叫作局部變量,由於它只能在該函數內部訪問函數

function fun(){
    //用關鍵字var定義局部變量str,
    var str='hello,life';
    //在函數做用域訪問局部變量str
    console.log(str);//輸出結果字符串:hello,life
}
//調用fun函數
fun();
//在全局做用域訪問局部變量str
console.log(str);//報錯,全局不容許訪問函數內部定義的局部變量

聲明提早

JavaScript變量的另外一種特別之處,能夠引用後面聲明的變量,而不會引起異常,這一律念成爲變量聲明提早。JavaScript變量感受上是被提高到了全部函數和語句以前,然而提高後的變量將返回undefined值,因此即便在使用或引用某個變量以後存在聲明和初始化操做,仍獲得undefined值this

  • 全局變量聲明提早
console.log(str);//不報錯,可是輸出結果:undefined
var str='hello';//定義全局變量str
console.log(str); //輸出結果字符串:hello

//上述代碼中的第一行輸出不會報錯,而是輸出undefined值,效果等同於下面的代碼
var str;//定義全局變量str,可是不初始化值
console.log(str);//不報錯,輸出結果undefined
str='hello';//對全局變量str進行初始化值
console.log(str);//輸出 字符串 hello
  • 局部變量聲明提早

定義在局部變量以前,先調用該函數內部的變量,結果不會報錯code

function fn(){
    console.log(str);//不報錯,輸出 undefined
    var str='hello';//定義全局變量 str
    console.log(str);//輸出字符串 hello
}
fn();
console.log(str);//報錯

//上述代碼中的第二行輸出不會報錯,而是輸出undefined,效果等同於下面代碼
function fn(){
    var str;//定義局部變量str,但未初始化值
    console.log(str);//不報錯,輸出結果undefined
    str='hello';//定義局部變量 str
    console.log(str);//輸出結果字符串 hello
}

按值傳遞

指將實參變量的值複製一份副本給函數的形參變量,JavaScript中爲函數傳遞參數時,都是按值傳遞,若是向函數傳遞的參數是原始類型數據,則在函數中修改參數變量的值,不會影響外部實參的變量生命週期

var n=100;//定義全局變量n
function fun(n){//參數變量也屬於局部變量
    n++;//修改的是局部變量的n的值
    console.log(n);//輸出的是局部變量的n的值
}
fun(n);//按值傳遞,方法內輸出101
console.log(n);//輸出全局變量的值 100

全局函數

函數與變量相似,具備全局做用域和函數做用域(局部做用域),與全局變量類似,全局函數是被定義在全局做用域的,任何位置均可以訪問或調用該函數ip

function fun(num1,num2){
    console.log(num1+num2);//輸出結果 3
}
fun(1,2);//調用fun同時傳入實參1和2

內部函數

一個函數被定義在另外一個函數的內部,被稱爲局部函數或者內部函數,與變量類似,局部函數只能在當前函數內部訪問,而不能在全局做用域中被訪問作用域

function fun(){//全局函數
    function inner(){//局部函數
        console.log('hello');
    } 
    inner();//調用正常
}
inner();//輸出報錯