作用域链 (这是一个纯概念性的东西, 面试也可能会问)
作用域链就是在访问一个变量的时候, 如果当前作用域内没有
会去自己的父级作用域, 也就是上一层作用域内查找, 如果找到就直接使用, 如果没有找到继续向上层查找
直到查找到 最顶层的全局作用域, 如果找到了直接使用, 如果没找到 报错提示变量不存在(未定义)
我们将这个一层一层向上查找的规律, 叫做作用域链
var num = 999
function fn1() {
var num = 100
function fn2() {
console.log(num) //打印的值 为 100
1. 先在当前作用域内, 也就是 fn2 函数内部开始查找变量 num, 然后发现 当前作用域内 没有这个变量
所以会去自己的父级的作用域内查找(也就是 fn1 这个函数内部)
2. 来到了自己父级内部查找, 此时找到了一个变量 num 他的值 为 100, 然后直接使用这个变量 并停止查找
}
fn2()
}
fn1()
`
var num = 999
function fn1() {
function fn2() {
console.log(num) //打印的值 为 999
1. 先在当前作用域内, 也就是 fn2 函数内部开始查找变量 num, 然后发现 当前作用域内 没有这个变量
所以会去自己的父级的作用域内查找(也就是 fn1 这个函数内部)
2. 来到了自己父级内部查找, 发现并没有一个叫做 num 的变量, 然后继续向上层查找, 也就是 全局作用域 内
3. 来到全局作用域内查找的时候 发现了一个叫做 num 的变量, 值为 999, 然后停止查找, 直接使用该变量
}
fn2()
}
fn1()
`
function fn1() {
function fn2() {
console.log(num)//num 找不到, 所以会报错
1. 先在当前作用域内查找, 也就是 fn2 内部, 发现没有, 去自己的父级查找, 也就是 fn1 内部
2. 来到了 fn1 内部查找, 发现没有, 去自己的父级查找, 也就是 全局作用域
3. 来到了全局作用域内查找, 发现还是没有, 然后停止查找, 返回一个 num 未定义的报错
4. 虽然 fn2 作用域内的子级作用域内(fn3函数内部) 有一个变量叫做 num 但是根据 作用域链的访问规则
我们并不会去这个 作用域内查找, 因为 作用域只会逐层向上查找, 并不会向下查找
function fn3() {
var num = 666
}
fn3()
}
fn2()
}
fn1()
作用域链的赋值规则
在给变量赋值的时候, 首先会去当前作用域查找, 如果有直接赋值, 并停止查找
如果没有, 会去自己的父级查找, 在父级找到直接修改值然后停止查找, 如果没有继续向自己的父级查找, 直到找到全局作用域
在全局作用域内, 找到直接赋值修改他的值, 如果没有找到, 那么会在全局作用域创建一个变量, 并赋值
function fn1() {
function fn2() {
num = 100
}
fn2()
}
fn1()
console.log(num) // 100
`
function fn1() {
var num = 999
function fn2() {
num = 100
在当前作用域内查找 num 发现没有, 会去自己的父级作用域内查找, 也就是 fn1 函数内部
在 fn1 函数内部发现一个变量 num 然后值为 999 我们会对这个变量做一个重新赋值的操作
也就是将他的值 重新修改为 100
}
fn2()
console.log(num) // 100
}
fn1()
console.log(num) // 未定义
`
var num = 666
function fn1() {
var num = 999
function fn2() {
num = 100
在当前作用域内查找 num 发现没有, 会去自己的父级作用域内查找, 也就是 fn1 函数内部
在 fn1 函数内部发现一个变量 num 然后值为 999 我们会对这个变量做一个重新赋值的操作
也就是将他的值 重新修改为 100
}
fn2()
}
fn1()
console.log(num) // 666
var num = 666
function fn1() {
function fn2() {
num = 100
在当前作用域内查找 num 发现没有, 会去自己的父级作用域内查找, 也就是 fn1 函数内部
在 fn1 函数内部, 发现没有 这个变量, 继续去自己的父级作用域查找, 也就是 全局作用域
在全局作用域发现了一个变量 叫做 num, 他的值是 666, 我们将这个变量重新赋值为 100
}
fn2()
}
fn1()
console.log(num) // 100