引擎和作用域的对话
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不能进行重新赋值操作
闭包笔记
如果不执行外部函数,内部作用域和闭包都无法被创建;
网友评论