1. 程式人生 > >TypeScript--函數作用域

TypeScript--函數作用域

位置 團隊 types 運行 轉換成 mea 函數表 lock 註意

函數作用域

1. 什麽是函數作用域?

個人理解:類似於玄幻小說裏的氣場或域,在該範圍內受到某種效果,這個函數就是類似於這個效果,只有在該範圍有用

function ShuaiGuo():void{
    var name:string = '劉德華'
    console.log(name)
}
ShuaiGuo()
console.log(name)

個人理解:函數放在內存的代碼段裏,而內存垃圾清理最常用機制之一標記清除(另一個是引用計數),當函數執行的時候標記為“進入環境”,當函數執行結束會變成“離開環境”變量後會被銷毀,下面的引用找不到

2. 什麽是全局變量?

個人理解:我們寫代碼時候命名要見名知意---從字面上理解“全局”函數向上尋找是window,在window下的變量,在函數內可以調用,函數外也可以調用

var name:string = '劉德華'
function ShuaiGuo():void{
    console.log(name)
}
ShuaiGuo()
console.log(name)

3. 什麽是局部變量?

局部,天氣預報經常說局部地區有雨,相對整個全局的某一部分有雨,這個範圍準確的說是,作用域的範圍

【註】

當局部變量和全局變量重名的時候,函數體內變量是起作用的;如果重名會導致:==變量提升==

var name:string = '劉德華'
function ShuaiGuo():void{
    //var name:string (聲明為空)
    console.log(name)//1. undefined  
    var name:string = '滑的溜'
    console.log(name) //2. 滑的溜
}
ShuaiGuo()
console.log(name)//3.劉德華 
【擴展】

3.1 什麽是函數提升?(ES5)

  • 函數聲明
  • 函數表達式
【註】只有函數聲明才存在函數提升,函數提升比變量提升優先級高

函數聲明語法

f('superman');
function f(name){
    console.log(name);
}

運行上面的程序,控制臺能打印出supemran。
函數表達式語法

f('superman');
var f= function(name){
    console.log(name);
}

運行上面的代碼,會報錯Uncaught ReferenceError: f is not defined(…),錯誤信息顯示說f沒有被定義。

==為什麽同樣的代碼,函數聲明和函數表達式存在著差異呢?==

這是因為,函數聲明有一個非常重要的特征:函數聲明提升,函數聲明語句將會被提升到外部腳本或者外部函數作用域的頂部(是不是跟變量提升非常類似)。正是因為這個特征,所以可以把函數聲明放在調用它的語句後面。如下面例子,最終的輸出結果應該是什麽?:

var getName = function(){
    console.log(2);
}
function getName (){
    console.log(1);
}
getName();

可能會有人覺得最後輸出的結果是1。讓我們來分析一下,這個例子涉及到了變量聲明提升和函數聲明提升。正如前面說到的函數聲明提升,函數聲明function getName(){}的聲明會被提前到頂部。而函數表達式var getName = function(){}則表現出變量聲明提升。

因此在這種情況下,getName也是一個變量,因此這個變量的聲明也將提升到底部,而變量的賦值依然保留在原來的位置。需要註意的是,函數優先,雖然函數聲明和變量聲明都會被提升,但是函數會首先被提升,然後才是變量。因此上面的函數可以轉換成下面的樣子:

function getName(){    //函數聲明提升到頂部
    console.log(1);
}
var getName;    //變量聲明提升
getName = function(){    //變量賦值依然保留在原來的位置
    console.log(2);
}
getName();    // 最終輸出:2

所以最終的輸出結果是:2。在原來的例子中,函數聲明雖然是在函數表達式後面,但由於函數聲明提升到頂部,因此後面getName又被函數表達式的賦值操作給覆蓋了,所以輸出2。

3.2 let關鍵字變量的作用域(ES6)

在ES5中,變量作用域只有全局和局部,並且是以函數劃分,在javascript語言中,並不適合大型開發,因為很容易內存泄露,javascript團隊,在ES6中推出了let關鍵字(生成一個塊級作用域,程序更有條例,簡潔優雅,但是感覺可讀性會下降了很多)

function ShuaiGe():void{
    var nameA:string = "劉德華"
    {
        let nameB:string = '古天樂'
        congsole.log(nameB)
    }
    congsole.log(nameA)
    congsole.log(nameB)
}
ShuaiGe()

TypeScript--函數作用域