作用域指的是一个变量和函数的作用范围,JS中函数内声明的所有变量在函数体内始终是可见的,在ES6前有全局作用域和局部作用域,但是没有块级作用域(catch只在其内部生效),局部变量的优先级高于全局变量。

变量提升

  1. var scope="global";
  2. function scopeTest(){
  3. console.log(scope);
  4. var scope="local"
  5. }
  6. scopeTest(); //undefined

上面的代码输出是undefined,这是因为局部变量scope变量提升了,等效于下面

  1. var scope="global";
  2. function scopeTest(){
  3. var scope;
  4. console.log(scope);
  5. scope="local"
  6. }
  7. scopeTest(); //undefined


注意**,如果在局部作用域中忘记var,那么变量就被声明为全局变量。

没有块级作用域

  1. var data = [];
  2. for (var i = 0; i < 3; i++) {
  3. data[i] = function () {
  4. console.log(i);
  5. };
  6. }
  7. data[0](); // 3
  8. data[1](); // 3
  9. data[2](); // 3

作用域链

每个函数都有自己的执行上下文环境,当代码在这个环境中执行时,会创建变量对象的作用域链,作用域链是一个对象列表或对象链,它保证了变量对象的有序访问。

作用域链的开始是当前代码执行环境的变量对象,常被称之为“活跃对象”(AO),变量的查找会从第一个链的对象开始,如果对象中包含变量属性,那么就停止查找,如果没有就会继续向上级作用域链查找,直到找到全局对象中