好程式設計師web前端帶你瞭解JS的作用域鏈
好程式設計師 web前端帶 你瞭解 JS的作用域鏈, 我們都知道 js 是一個基於物件的語言,系統內建各種物件。
而 window 作為一個天然存在的全域性物件,它承擔了所有全域性資源的儲存。
我們使用的任何全域性變數,都是 window 下的。也就是說,在 js 中,實際上沒有任何物件、方法是可以獨立的,它們必須依賴於某個物件才可以被訪問或執行。
就像 alert() ,它的完整寫法是 window.alert()
parseInt(), 完整寫法是 window.parseInt()
所有放在 window 物件下的資源,訪問時可以預設省略 window
但有一種情況非常特殊,例如函式中的區域性變數:
function Person(){
var name = “abc” ;
}
當我們試圖訪問這個 name 屬性時
console.log(newPerson().name);
結果是 undefined
我們只能在函式內部訪問:
function Person(){
var name = “abc”;
console .log(name);
}
這種屬性,在建構函式中,也被稱為私有屬性,我們必須提供一種對外公開的方法才可以被外界訪問。例如:
function Person(){
var name = “abc” ;
this .getName = function (){
return name;
}
this .setName= function (_name){
name = _name;
}
}
這是一個典型的作用域問題 , 似乎我們每個人都知道。
但這似乎也違反了我們的一個常識:那就是在 js 中,所有資源都必須依賴物件才能存在,不可獨立使用。比如說:
function aaa(){
function bbb(){ }
bbb();
}
這段程式碼看上去並沒有錯,但是請問 bbb 這個函式為什麼可以獨立存在呢?如果我們把它換成這樣:
function aaa(){
function bbb(){ }
window .bbb();
}
結果是執行錯誤!
那如果換成這樣呢?
function aaa(){
function bbb(){ }
this .bbb();
}
結果還是執行錯誤!
那麼我們不禁要發問了, bbb 這個函式到底是屬於哪個物件的?
當我們在呼叫一個函式的時候,瀏覽器會為這個函式的執行開闢一塊記憶體區域用來儲存這個方法在執行的臨時資料。而物件作為 js 的基本儲存單位,因此,臨時資料實際上都被儲存到了一個物件當中,這個物件,就是我們平時所說的 執行上下文環境
當我們呼叫 aaa 函式時,例如 window.aaa()
瀏覽器會為這一次函式的執行,建立一個執行上下文環境物件,我們暫時給它起個名字,叫做 contextAAA 吧,當然它是臨時的,因為函式執行完它也就消失了。
那我們的程式碼實際上會變成這樣:
function aaa(){
function bbb(){ }
contextAAA .bbb();
}
儘管 contextAAA 物件是看不見的,但它確實存在。
而當我們執行 bbb 函式時,瀏覽器會再次為這一次函式呼叫建立一個臨時的執行上下文環境,我們暫且叫它 contextBBB
那麼 contextAAA 和 contextBBB以及window 之間會形成鏈條關係,
舉個例子來說明吧
var num = 888;
function aaa(){
var num = 100;
function bbb(){
var num= 200;
console .log(num);
}
bbb();
}
aaa();
那麼 contextAAA 如下:
contextAAA = {
num : 100,
bbb : function (){ … },
parentContext: window // 父級上下文物件
}
那麼 contextBBB 如下:
contextBBB = {
num : 200,
parentContext: contextAAA // 父級上下文物件
}
因此我們發現,在父級上下文物件中,我們沒有辦法訪問到子級上下物件,這是一個單向連結串列,這就是全域性不能訪問區域性的原因。
而 bbb 函式中列印出的 num 應該是多少呢?這取決在上下文物件中的查詢順序,順序大概是這樣的:
首先在當前上下文物件 contextBBB 中,找一下有沒有 num 變數,找到就直接列印。以我們目前的程式碼看,結果應該是 200
我們把程式碼改造一下:
var num= 888;
function aaa(){
var num = 100;
function bbb(){
console .log(num);
}
bbb();
}
aaa();
由於這次在 contextBBB 物件中找不到 num 變數了,因此它會從父級上下文物件中查詢,也就是 contextAAA 裡面的 num ,因此列印的結果是 100;
我們再把程式碼改造一下
var num= 888;
function aaa(){
function bbb(){
console .log(num);
}
bbb();
}
aaa();
由於這次連 contextAAA 物件裡也找不到了,會再次向它的父級上下文物件,也就是 window 查詢,因此列印結果是 888
contextAAA 和 contextBBB 的父子關係,在你寫程式碼的一刻就決定了,這就是作用域。
function aaa(){
var
num = 10;
function bbb(){ console .log(num); }
}
而程式碼執行時,產生的上下文物件,是連結串列的關係。這就是我們所說的作用域鏈,它的原理跟原型鏈是一樣的。
理解了這一點,也能弄明白閉包的原理。
function aaa(){
var num = 10;
return function bbb(){ console .log(num); }
}
aaa( )( )
儘管 bbb函式透過return在全域性範圍被執行了,但作用域的連結串列關係並沒有發生改變,因此,bbb函式依然可以訪問num這個區域性變數。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2644218/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- web前端學習教程:JS的作用域鏈Web前端JS
- 好程式設計師web前端教程分享js閉包程式設計師Web前端JS
- 好程式設計師web前端教程分享js模板模式程式設計師Web前端JS模式
- 好程式設計師Web前端教程分享新手應該瞭解的Cookie知識!程式設計師Web前端Cookie
- 好程式設計師web前端分享CSS屬性組成及作用程式設計師Web前端CSS
- 好程式設計師web前端學習路線分享Jsonp詳解程式設計師Web前端JSON
- 好程式設計師web前端教程之Node.Js流程程式設計師Web前端Node.js
- 好程式設計師web前端細解cookie那些事程式設計師Web前端Cookie
- 好程式設計師web前端教程:字串程式設計師Web前端字串
- 好程式設計師web前端學習路線分享瞭解AJAX是什麼程式設計師Web前端
- 好程式設計師web前端分享js剪下板Clipboard.js 使用程式設計師Web前端JS
- 好程式設計師Web前端分享前端CSS篇程式設計師Web前端CSS
- 好程式設計師web前端分享web測試之Js中的變數程式設計師Web前端JS變數
- 好程式設計師web前端教程分享js中的模組化二程式設計師Web前端JS
- 好程式設計師web前端教程分享js中的模組化一程式設計師Web前端JS
- 好程式設計師web前端分享JS引擎的執行機制程式設計師Web前端JS
- 好程式設計師web前端分享應該怎樣學好web前端?程式設計師Web前端
- 好程式設計師web前端教程分享Vue.js面試題程式設計師Web前端Vue.js面試題
- 好程式設計師web前端教程分享JS基礎知識程式設計師Web前端JS
- 好程式設計師web前端學習教程之Node Js流程程式設計師Web前端JS
- 好程式設計師web前端教程分享js reduce方法使用教程程式設計師Web前端JS
- 好程式設計師web前端分享js實現實戰案例程式設計師Web前端JS
- 好程式設計師Java學習路線帶你5分鐘瞭解希爾排序程式設計師Java排序
- js的作用域、作用域鏈JS
- 好程式設計師web前端分享web前端入門知識程式設計師Web前端
- 好程式設計師web前端精講 web前端三要素程式設計師Web前端
- 好程式設計師帶你認識“jQuery”程式設計師jQuery
- 好程式設計師web前端分享如何理解JS的單執行緒程式設計師Web前端JS執行緒
- 好程式設計師Web前端中的js能運用到哪些方面程式設計師Web前端JS
- 好程式設計師web前端教程分享web前端基礎知識程式設計師Web前端
- js的作用域和作用域鏈JS
- js的作用域與作用域鏈JS
- 好程式設計師分享Web前端開發工具程式設計師Web前端
- 好程式設計師web前端教程:Math函式程式設計師Web前端函式
- 好程式設計師web前端教程分享CSS技巧!程式設計師Web前端CSS
- 好程式設計師web前端分享Cookie知識程式設計師Web前端Cookie
- 好程式設計師web前端分享前端 javascript 練習題程式設計師Web前端JavaScript
- 程式設計師,谷歌帶來的這場變革,你瞭解嗎?程式設計師谷歌