變數的作用域Scope:ES6之前
function test() {
var a = 10
console.log(a) //20 -> a 只有在這個function才會被找到
}
test()
console.log(a) //會報錯 -> 在function test以外會找不到a
var a = 10 //全域變數
function test() {
console.log(a) //10
console.log(b) //undefined
}
test()
console.log(a) //10
console.log(b) //undefined
var b = 20 //全域變數
//a 是全域變數不管在function內還是外都可以被找到,function會往上找,不會往下找(所以b會undefined)。
var a = 20
function test2() {
var a = 10
consolse.log(a) //10
}
test2()
console.log(a) //20
//都是找a,function自己有就不會往外找,外面的也是找到全域的a(沒有就報錯,不會往function裡面找)
//------------------------------
var b = 20
function test2() {
b = 10 //b沒有變數宣告,不會受Scope影響
console.log(b) //10 先往外找到有宣告的b=20然後直接改成10印出
}
test2()
console.log(b) //10 -> 到這一樣因為上面test2()做了改成10,所以也會是10
//------------------------------
function test3() {
c = 10
console.log(c) //10
}
test3()
console.log(c) //10
// 因為沒有做宣告這件事但c自己被程式宣告成var c,所以c=10都會被找到。看起來好像很方便,但可能會發生跟預期行為不一樣的事。所以變數一定都要經過宣告。
var a = "global"
function test() {
var a = "test scope a"
var b = "test scope b"
console.log(a, b) //test scope a test scope b
function inner() {
var b = "inner scope b"
console.log(a, b) //test scope a inner scope b
}
inner()
}
test()
console.log(a) //global
每個作用域都有自己的變數,沒有才會往外找。
var a = "global a"
function test() {
var b = "test scope b"
console.log(a, b) //global a test scope b
function inner() {
var b = "inner scope b"
console.log(a, b) //global a inner scope b
}
inner()
}
test()
console.log(a) //global a
當inner()裡面沒有a時會往test()找,test()沒有的話會再往外找,最後在全域找到 a = "global a"。
inner scope -> test scope -> global scope
這一個層層往上找的過程會構成一個scope chain(作用域鏈)
scope chain(作用域鏈)
var a = "global"
function test2() {
var a = 10
test1()
}
function test1() {
console.log(a) //global -> 上一層是global不會因為test2呼叫而傳入var a = 10。
}
test2()
O:test1 scope -> global scope
O:test2 scope -> global scope
X:test1 scope -> test2 scope -> global scope
scope chain是由程式碼放的位置決定的,跟在哪邊呼叫沒有關係(執行順序)。
(test1沒有在test2內層)。
你會想問我為什麼沒有講變數的作用域Scope:ES6之後嗎?
因為我放在 偉大航道的盡頭 啊不是,是在 Day15:ES6 I 就是用let與const來宣告會從function變成block{}
啦,這邊就不重覆再講一次了,直接結束這一回合,還賺一波點閱?。(誒!可以這樣操作的嗎?)