作用域与作用域链
作用域
作用域简单来说就是: 变量或函数在哪些范围内可以用,而在其他部分要用就得重新定义
作用域与this指向的状态是不一样的:
- 作用域的范围是静态的,在代码编写的时候就已经确定
- this的指向则是动态的,随着调用对象的不同而改变
作用域与执行上下文的不同
- 作用域是静态的,代码编写好后,作用域就被确定,不再变化
- 执行上下文会在函数调用前产生,调用结束后被释放,尤其指的是函数执行上下文
- 执行上下文是从属与当前的作用域中的
作用域的分类:
- 全局作用域
- 函数作用域
- 块级作用域(ES6以后拥有)
从一道题目弄清作用域个数的计算,及执行上下文是从属与当前的作用域中是什么意思:
var a = 10
var b = 20
function func(x){
var a = 100
var c = 300
console.log('fn()', a, b, c, x) //
function bar(x){
var a = 1000
var d = 400
console.log('bar()', a, b, c, d, x)
}
bar(100)
bar(200)
}
func(10)
作用域链
作用域链的概念十分简单: 从当前作用域向上出发,到全局作用域为止,去寻找变量,能够找到就返回其变量值, 找不到就报错
var a = 123
function test () {
var a = 10
console.log(a)
console.log(b) // 报错: b is not defined
}
test()
最后来几道面试题,给大家巩固一下作用域与作用域链的知识
// 面试题1
var x = 10
function func() {
console.log(x)
}
function show(f) {
var x = 20
f()
}
show(func) // 猜猜结果是啥
// 面试题2
var fn = function () {
console.log(fn)
}
fn() // 猜猜结果是啥
var obj = {
fn2: function () {
console.log(fn2)
}
}
obj.fn2() // 猜猜结果是啥
答案是
10
fn函数对象
报错: fn2 is not define
第一题,考查的是: 作用域链是静态的,在代码编写的时候就已经确定,并且不再改变(代码改变,会改)
第二题,考查的是: 在作用域链中查找变量
第三题, 考查的还是在作用域链中查找变量,但是增加了迷惑性