作用域
- 全局作用域(global/window)
- 函數(shù)作用域/局部作用域(function)
- 塊狀作用域({})
- 動態(tài)作用域(this)
1况脆、全局作用域
在最外層使用var定義全局作用域的變量荐操。
var course = "es6"
在任意位置創(chuàng)建未定義的變量辛块。
function foo () {
course = "es6"
}
// 在此處及任何位置都可以調(diào)用
console.log(course)
(不建議使用)而在在外層,使用let定義變量時竟纳,它的作用域為全局塊作用域樱报。
let a3 = 3
console.log("a3" in window); // false
以上定義全局作用域的三種方法總結(jié)為:
- 使用var,是定義了當前作用域的一個變量葡粒,可以使用window調(diào)用,但不能使用delete刪除膜钓。
- 未定義的變量嗽交,同樣可以使用window調(diào)用,但其作為window對象的一個屬性颂斜,可以使用delete刪除夫壁。
- 使用let只是在當前作用域塊定義了一個變量,不是window的屬性沃疮,所以也無法使用window調(diào)用盒让。
var a1 = 1
a2 = 2
let a3 = 3
console.log(window.a1, 'a1' in window) // 1 true
console.log(window.a2, 'a2' in window) // 2 true
console.log(window.a3, 'a3' in window) // undefined false
2梅肤、函數(shù)作用域
在函數(shù)內(nèi)部定義的變量,就成為局部作用域邑茄,只作用于函數(shù)內(nèi)部姨蝴。
function bar() {
var testValue = 'inner'
}
console.log(testValue) // 報錯:ReferenceError: testValue is not defined
如果想兌取函數(shù)內(nèi)的變量,必須使用return或者閉包肺缕,這里著重描述一下閉包左医。
閉包
一個函數(shù)和它的周圍狀態(tài)的引用捆綁在一起的組合。
當函數(shù)執(zhí)行的時候同木,其內(nèi)部的自由變量(未在函數(shù)內(nèi)部定義)的取值浮梢,是根據(jù)函數(shù)定義的地方向上查找它的值。
function test() {
const a = 1
return function () {
console.log('a', a)
}
}
const fn = test()
const a = 2
fn() // a 1
3彤路、塊狀作用域
有{}的就是塊秕硝,在ES5中使用var定義變量時沒有塊作用域的,會因為var的變量提升機制洲尊,將變量提升到當前作用域的最上層远豺。
if (true) {
var a = 1
}
console.log(a); // a
相當于
var a
if (true) {
a = 1
}
console.log(a);
在ES6中,使用let聲明變量坞嘀,就可用吧變量的作用域限制在當前塊中憋飞。
if (true) {
let a = 1
}
console.log(a); // a is not defined
動態(tài)作用域
window.a = 3
function test() {
console.log(this.a)
}
test.bind({
a: 2
})() // 2
test() // 3
通俗的講變量的作用域是在定義時決定而不是執(zhí)行時決定,也就是說詞法作用域取決于源碼姆吭,通過靜態(tài)分析就能確定,因此詞法作用域也叫做靜態(tài)作用域唁盏。 相反内狸,只能在執(zhí)行階段才能決定變量的作用域,那就是動態(tài)作用域厘擂。