在昨天我們提到了5個問題
今天就來好好講解一下這5個問題
因為 var 的作用域是整個 function scope ,用 let、const 當然也可以,可是這樣就代表了他只能作用在當前那個 block,除非是定義在最上層的 function scope,不然很難共享,而 var 有 hosting 至少可以保證不會出現 error,當然也有人說 const 和 let 可以完全取代 var,這件事就見仁見智了,不過盡量避免使用 var 宣告這一點是不會錯的。
這邊可以稍微提一個有趣的東西 語彙範疇(Lexical Scope),js 是採用 Lexical Scope 設計的,當然還有另一個叫做動態範疇(dynamic scope)的,這邊就不多說了,目前不會碰到。
知道了 Lexical Scope 可以幹嘛呢,他有另一個講法 Static Scope,意思就是說是靜態的,也就是說我們定義在哪裡就會作用在哪裡,所以就可以有 local scope 、global scope 的差別。
現在我們知道 var 定義的作用域是 function scope ,那我們就可以實現一件事情:
function scopeCheck(){
var i=2
function scope2(){
console.log(i)
}
scope2() // 2
}
scopeCheck()
你可以發現 i 並不是 scope2 的變數 ,i 也沒有經過 props 傳遞,但 scope2 卻可以輕易地擷取 i 的值,這時 i 對於 scope2 來說就是一個自由變數。
在 Lexical Scope 的設定內,如果一個變數被使用,但在他這個 scope 內找不到被定義的值的話,他就會一步一步往外面的 scope 找,直到找到這個變數被給值,所以我如果再用一個 scope1.5()包住 scope2(),並在裡面定義 i=3的話,scope2就會印出 3。如果一直找到 global scope 都沒有的話,就會報錯。
不管是var let const 都可以有這樣的效果,這樣是不是對作用域(scope)有更深入的理解了呢。
這個問題在講解 let 時因該就舉例得相當清楚了,這邊快速地複習一下,之所以不用 var 的原因是因為在 for loop 等循環區域裡,var 會被重複定值,造成區域變數互相汙染。
let 和 var 最大的差別在於:
如果還有疑問的話,可以回去看一下昨天講解 let 的部分
這是因為 var 的特性 hosting,用起來方便但非常危險,這邊做個複習,hosting 可以讓你不用宣告變數就提前使用,但給值還是要按照寫的順序來。
首先必須要知道,函式宣告有分為函式陳述式(function expression) 和 函式運算式(function declaration) 兩種。
這兩個最大的差別就是 function expression 會回傳一個值,並且可以被指定給一個變數,例如 arrow function :
const fun1 = () =>{console.log('expression')}
註:指定給 fun1 這個變數的,就是一個典型的匿名函式(anonymous function) ,且有匿名就有具名,只要是你有命名的函式,就可以被稱作具名函式(named function)。當然匿名函式雖然方便,但維護不易,還是建議乖乖把名字取好,不要跟自己過不去。
註:這邊提個題外話, expression 就是表達的意思,只要是你有給值的,例如:
var i=1
這樣也是一個 expression。
而 function declaration 就是用 function 宣告的函式,他不能被指定給一個變數,必須調用他才能實作功能。
function fruitName() {
const fruit='apple'
console.log(fruit);
}
fruitName()
這邊我們回到問題,arrow function 是 function expression,所以不能用 function 宣告。
我是 Chris,以上這些是關於碰到 scope 時可能會碰到的相關議題,裡面也包含了我遇到的一些問題,就一起帶出來給大家了,當然,我還有很多沒提到的部分,如果後面有碰到的話會再額外提出來給大家,明天見!