词法作用域
定义在词法阶段的作用域,开始时,编译器做语法分析的时候,确认js里各个词法所在的作用域。
js里只有全局作用域和函数作用域,这里简单介绍下js的作用域。
js作用域
看下面代码:
var a = 1;
var b = 0;
function foo() {
var a = 2;
console.log(a); //2
console.log(b); //0
}
foo();
console.log(a); //1
1、在foo函数里,在console.log(a),对a进行RHS查询,发现在当前作用域存在变量a,如果foo里没有a就往上一层(全局)去查找
2、在foo函数里,在console.log(b),对b进行RHS查询,发现在当前作用域不存在变量b,然后往上一层(全局)去查找b,发现存在变量b,获取b的值。
在词法分析阶段,会确认在全局作用域里有a,b这两个变量,函数foo作用域里有a这个变量
但是,有些方法可以欺骗或者动态生成作用域。
例如:eval、setTimeout、with等
eval
eval函数可以理解为在当前作用域插入一段代码。
如下:
var b = 2;
function foo() {
eval('var b=1')
console.log(b); //1
}
foo();
console.log(b); //2
在开始的词法分析中,foo函数作用域并不存在变量b,然而在引擎执行代码的时候,到eval函数执行,就强行在foo函数作用域中插入变量b
setTimeout
定时器函数是一个异步函数,第一个参数中字符串的执行作用域是全局作用域,类似上面动态插入变量。
var b = 1;
function foo() {
setTimeout('var b =2', 0);
setTimeout('console.log(b)', 0); //2
}
foo();
console.log(b); //1
with
扩展一个语句的作用域链。
在一个对像是扩展属性,如果属性存在就修改属性值,如果不存在就挂载在全局对象上,类似于在函数里不用var声明的变量都挂在window对象上。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。