1、js中的词法做用域和动态做用域javascript
词法做用域也就是在词法阶段定义的做用域,也就是说词法做用域在代码书写时就已经肯定了。 java
js中其实只有词法做用域,并无动态做用域,this的执行机制让做用域表现的像动态做用域,this的绑定是在代码执行的时候肯定的。函数
example1: 理解词法做用域 this
记住js中只有词法做用域没有真正的动态做用域,做用域是在代码书写时肯定的对象
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar();
//1
输出是1,函数在哪里调用没有关系,变量的位置在编译的词法分析阶段就肯定了。blog
当调用foo时,会对value进行一次RHS查询,在当前函数做用域中没有查找到会查找到最外层的做用域,也就是全局做用域定义的value。ip
2、修改词法做用域作用域
在代码书写时,做用域(词法做用域)就已经肯定了,可是可不能够再修改呢?it
经过eval和with均可以用来修改词法做用域。io
eval:
function foo(str, a) { eval(str) console.log(a, b)//1,3 } var b = 2; foo("val b = 3", 1)
with:
用来重复引用同一个对象中的多个属性的快捷方式
能够理解为修改对象中多个属性的值的快捷方式
function foo(obj) { with(obj) { a = 7 } } var obj1 = { a: 2 } var obj2 = { b: 3 } foo(obj1) console.log(obj1)// {a=7} console.log(a) //7 foo(obj2) console.log(obj2)//{b:3} console.log(a)//7
with能够定义一个词法做用域, 值得注意的是with中定义的a=2会在全局做用域中包含一个a变量。
3、函数做用域和块做用域
一、建立做用域的方式
a)经过函数建立局部做用域
一、经过函数声明的方式建立
二、经过函数表达式建立:
匿名函数表达式和具名函数表达式
区别函数表达式和函数声明的方式就是看声明的第一个关键字是不是function开头
b)经过with、try...catch、let和const建立块做用域
值得提的是let和const定义的块做用域
let在声明变量时,会将变量附加在一个已经存在的块做用域上,通常是{}(隐式附加),let声明的变量是在js运行的时候才存在的。