Open iniaks opened 8 years ago
一套用来存储,调用变量的规则被称为作用域
JS不是提前编译的语言,传统编译语言在执行前有三个步骤:
JS引擎比这个要复杂的多,因为JS是边编译边执行,所以它花了大量的步骤来针对编译过程进行性能优化
当变量出现在赋值操作左侧时编译器会进行LHS(左侧)查询,出现在右侧时进行RHS(非左),这两种操作的含义为“赋值操作的左侧和右侧”,这并不等于“=操作符的左侧和右侧”。赋值操作有很多种形式
LHS代表着赋值操作的目标 RHS代表着赋值操作的源头
比如
function foo (a) {
var b = a
return a + b
}
var c = foo(2)
在这个例子中,有三处LHS查询: 为c查询,为a查询,以及为b查询 四处RHS查询: 为c赋值,为b赋值,为a+b中的a,b赋值
词法作用域是定义在词法阶段的作用域,它由变量和块作用域在代码中的位置来决定。作用域查找会在找到第一个匹配的标示符时停止。
通过with和eval可以达到欺骗词法的目的,均不推荐使用,它们都会严重影响JS的性能
函数作用域:一个函数的所有变量都可以在整个函数的范围内使用及复用。
a = 2
var a
console.log(a) //输出2
console.log(a) //输出undefined
var a = 2
function foo () {
var a = 2
function bar () {
console.log(a)
}
return bar
}
var baz = foo()
baz()
闭包使得函数可以继续访问定义时的词法作用域
function foo () {
var a = 2
function baz () {
console.log(a)
}
bar(baz)
}
function bar(fn) {
fn()
}
当函数在别处调用时都可以观察到闭包
本质上,无论何时,如果将函数当做第一级的值类型并到处传递,就可以观察到闭包
最基本和常见的例子:
for (var i=1; i<5; i++) {
setTimeout( function timer() {
console.log(i)
}, i*1000)
}
读书笔记