前言
JavaScript 中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲!
作用域(Scope)
1. 什么是作用域
作用域是在運行時代碼中的某些特定部分中變量,函數(shù)和對象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見性。可能這兩句話并不好理解,我們先來看個例子:
function outFun2() { var inVariable = "內(nèi)層變量2";}outFun2();//要先執(zhí)行這個函數(shù),否則根本不知道里面是啥console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined從上面的例子可以體會到作用域的概念,變量 inVariable 在全局作用域沒有聲明,所以在全局作用域下取值會報錯。我們可以這樣理解:作用域就是一個獨立的地盤,讓變量不會外泄、暴露出去。也就是說作用域最大的用處就是隔離變量,不同作用域下同名變量不會有沖突。
ES6 之前 JavaScript 沒有塊級作用域,只有全局作用域和函數(shù)作用域。ES6 的到來,為我們提供了‘塊級作用域',可通過新增命令 let 和 const 來體現(xiàn)。
2. 全局作用域和函數(shù)作用域
在代碼中任何地方都能訪問到的對象擁有全局作用域,一般來說以下幾種情形擁有全局作用域:
最外層函數(shù) 和在最外層函數(shù)外面定義的變量擁有全局作用域
var outVariable = "我是最外層變量"; //最外層變量function outFun() { //最外層函數(shù) var inVariable = "內(nèi)層變量"; function innerFun() { //內(nèi)層函數(shù) console.log(inVariable); } innerFun();}console.log(outVariable); //我是最外層變量outFun(); //內(nèi)層變量console.log(inVariable); //inVariable is not definedinnerFun(); //innerFun is not defined所有末定義直接賦值的變量自動聲明為擁有全局作用域
function outFun2() { variable = "未定義直接賦值的變量"; var inVariable2 = "內(nèi)層變量2";}outFun2();//要先執(zhí)行這個函數(shù),否則根本不知道里面是啥console.log(variable); //未定義直接賦值的變量console.log(inVariable2); //inVariable2 is not defined所有 window 對象的屬性擁有全局作用域
一般情況下,window 對象的內(nèi)置屬性都擁有全局作用域,例如 window.name、window.location、window.top 等等。
全局作用域有個弊端:如果我們寫了很多行 JS 代碼,變量定義都沒有用函數(shù)包括,那么它們就全部都在全局作用域中。這樣就會 污染全局命名空間, 容易引起命名沖突。
// 張三寫的代碼中var data = {a: 100}// 李四寫的代碼中var data = {x: true}這就是為何 jQuery、Zepto 等庫的源碼,所有的代碼都會放在
新聞熱點
疑難解答
圖片精選