你不知道的js-作用域

2019-03-21  本文已影响0人  18dian

引擎和作用域的对话

function foo(a) {
  var b = a;
  return a+b;
}

var c = foo(2)

引擎:作用域,我需要为c进行LHS引用,你见过它吗?
作用域:编译器那家伙刚声明了它,给你
引擎:好的,谢谢,我把foo(2)赋值给它
引擎:作用域,我要为foo进行RHS查询
作用域:给你,是个函数
引擎:好的我执行一下
引擎:作用域,我要为a进行LHS查询
作用域:编译器把它声明为一个形参了,给你
引擎:把2赋值给a
引擎:作用域,我需要为b进行LHS引用,见过吗?
作用域:编译器声明了它,给你
引擎:作用域,我需要为a进行RHS引用
作用域:我见过它,它是2,给你
引擎:把2赋值给b
引擎:我需要对a和b进行RHS引用
作用域:它是2和2

ReferenceError同作用域判别失败相关,TypeError属于作用域判别成功了,但是对结果的操作是不合法的;
如果查找的目的是对变量进行赋值,就是LHS查询,如果查找的目的是找到变量的值,进行的是RHS查询;

function foo() {
  function bar(a) {
    var i = 3;
    console.log(a+i)
  }
  for(var i = 0; i<10;i++) {
    bar(i*2)
  }
}

foo()

在bar函数中,当没有用var对i进行声明时,引擎会为i进行LHS查询,在bar作用域中没有找到,向上一级foo函数作用域中去找,结果找到了for循环中的var i = 0;接下来,引擎会将3赋值给for循环中的i,所以i的初始值永远是3,永远小于10,就会造成死循环;

当有var时,引擎在当前作用域中已经找到了i,并且将值赋值给当前作用域中的变量i,就不会再去影响for循环中的初始值i,此时的var i = 3,只能在bar函数作用域中能访问到

当将for循环中的var变成let,for循环也就变成了一个单独的块级作用域,bar也是一个单独的函数作用域,它们两个属于兄弟关系

当将for循环中的var变成const,直接报错,因为const不能进行重新赋值操作

闭包笔记

如果不执行外部函数,内部作用域和闭包都无法被创建;

上一篇 下一篇

猜你喜欢

热点阅读