作用域
在es6之前JavaScript作用域分两种:全局作用域与函数作用域。作用域可用于隔离变量,在不同的作用域下使用同名变量并不会冲突。
作用域与执行上下文
作用域与执行上下文的区别:
- 创建的时间:
- 全局作用域最开始就确定了,函数作用域在函数定义时确定;
- 全局执行上下文是在全局作用域确定好之后,代码执行之前确定。函数执行上下文是在调用函数时,执行函数之前确定;
- 静态与动态
- 作用域一经确定就一直存在并不再更改。
- 函数执行上下文随着每次函数的调用都会被创建,随着函数调用结束会自动释放。
联系:
执行上下文可以说是属于作用域的一部分。
作用域链
作用域链由多个作用域组成,在访问一个变量时先在自身的作用域查找,如果没有找到就进入上一级作用域查找,以此类推直到全局作用域。(是一个由内而外的查找过程)
var a = 1;
function fn1(){
var b = 2;
function fn2(){
var c = 3;
function fn3(){
var a = 100;
//先在自身找到a = 100
console.log(a,b,c); // 100,2,3
}
fn3();
}
fn2();
}
fn1();
练习
//case 1
var obj = {
fn2: function () {
console.log(fn2)
}
}
obj.fn2() //报错
//case 2
var obj = {
fn2: function () {
console.log(this.fn2)
}
}
obj.fn2() //输出function fn2
对于case1,运行obj.fn2()
时先在函数内部找,没找到则根据作用域链跳到全局作用域找也没有fn2,只有obj这个对象,因此报错。
对于case2,运行obj.fn2()
时先在函数内部找this.fn2即obj.fn2,没找到则根据作用域链跳到全局作用域找,可以找到obj对象然后返回obj.fn2。(也就是说在全局作用域下对象内部的属性并不能直接被看到,需要通过对象去查找)