作用域
作用域是可访问的变量的集合。在JavaScript中,作用域为可访问变量,对象,函数的集合。
作用域分为 全局作用域 和 局部作用域 ,其中局部作用域又称为 函数作用域 。
ES6新增 块级作用域 。
全局作用域
全局作用域是设置在最顶级域window里面的,当前页面任何地方都可获取到的。
var a = 1 // 全局变量
console.log(window.a) // 1
b = 2 // 全局变量
console.log(window.b) // 2
function fun(){
c = 3 // 全局变量
}
fun()
console.log(window.c) // 3
window.d = 4 // 全局变量
console.log(window.d) // 4
局部作用域(函数作用域)
函数内部声明的变量,只能在函数这个局部内被获取,函数外是没办法获取到的。
function fun(){
var a = 1 // 局部变量
}
console.log(window.a) // undefined
console.log(a) // Uncaught ReferenceError: a is not defined
function fn(){
var a = b = 10 // a->局部变量 b->全局变量
}
fn()
console.log(a) // Uncaught ReferenceError: a is not defined
console.log(b) // 10
ES6块级作用域
JavaScript中{}内的代码块,称为块级。只能在当前{}内被获取,{}外获取不到。通过let/const声明。
{
let a = 1
}
console.log(a) // Uncaught ReferenceError: a is not defined
for(let i = 0; i < 5; i++) {}
console.log(i) // Uncaught ReferenceError: a is not defined
if(true){
let a = 1
}
console.log(a) // Uncaught ReferenceError: a is not defined
作用域链
var a = 100
function fn1() {
function fn2() {
console.log(a) // 100
}
fn2()
}
fn1()
在fn2中输出a,先从fn2中找,找不到就从fn1中找,直到找到全局作用域,这种一层一层的关系,就叫 作用域链 。
注意:
var x = 10
function fn1() {
console.log(x)
}
function fn2() {
var x = 20
fn1() // 10 而不是20
}
fn2()
注:在 fn1 函数中,取变量 x 的值时,要到创建 fn1 函数的那个作用域中取,而不是调用 fn1 函数的作用域中取。
例:
var a = 10
function fn1() {
var b = 20
function fn2() {
console.log(a + b)
}
return fn2
}
var x = fn1(), b = 200
x() // 30
fn1()返回的是 fn2 函数,赋值给 x。执行 x(),即执行 fn2 函数代码。取 b 的值时,直接在 fn1 作用域取出。取 a 的值时,试图在 fn1 作用域取,但是取不到,只能转向创建 fn1 的那个作用域中去查找,结果找到了,所以最后的结果是 30