1、什麼是做用域javascript
簡單來講,做用域就是定義變量和函數的區域,變量和函數在該區域能夠被訪問。java
須要注意的有三點:閉包
訪問變量時,應從變量定義的做用域沿着做用域鏈向上查找函數
var name = '小明'; function fn1() { var name = "小紅"; function fn2() { console.log('方法fn2中打印name:' + name); // 方法fn2中打印name:小紅 } fn2(); } fn1();
函數做用域只有函數才能建立,而且在該做用域在函數定義時就已經肯定了code
// 例子1 var name1 = '小明'; function fn1() { console.log('方法fn1中打印name1:' + name1); // 方法fn1中打印name1:小明 } function fn2() { var name1 = '小紅'; fn1(); console.log('方法fn2中打印name1:' + name1); // 方法fn1中打印name2:小紅 } fn2(); // 例子2 var name2 = '小明'; function fn3() { var name2 = '小紅'; return function() { console.log('閉包函數中打印name2:' + name2); // 閉包函數中打印name2:小紅 } } fn3(); // 例子3 var name2 = '小明'; function fn3() { var name2 = '小紅'; fn4 = function() { console.log('閉包函數中打印name2:' + name2); // 閉包函數中打印name2:小紅 } } fn3(); // 必須執行fn3方法,不然函數做用域中的js代碼不會被預解析和執行(Uncaught ReferenceError: fn4 is not defined) fn4();
JavaScript只有全局做用域和函數做用域(或者說局部做用域)。ES5是不存在塊級做用域的(例如 if 和 for 體現了沒有塊級做用域),ES6的出現 提供了兩個定義變量的方式 let/const ,纔有了塊級做用域。ip
// 例子1 if (true) { var name1 = "小明"; } console.log(name1); // 小明 (name1能夠被打印說明name1爲全局的,不存在塊級做用域) // 例子2 if (true) { const name2 = "小明"; } console.log(name2); // Uncaught ReferenceError: name2 is not defined
2、做用域鏈作用域
瞭解了做用域後,做用域鏈就好說了,那麼什麼是做用域鏈呢?通俗點講,當你聲明一個函數時,函數做用域一級一級向上包裹起來,這就是做用域鏈。io
須要注意的有兩點:console