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運行的時候才存在的。