犀牛書學習筆記(6):理解做用域和做用域鏈

任何語言都有做用域,javascript的做用域很是的特殊,實現的是一個做用域鏈,要理解其對象和函數,不可避免須要先理解其做用域和做用域鏈。在函數章節,簡單的描述了做用域鏈的概念,本篇嘗試對其進行透徹的分析研究。javascript

變量做用域java

在第一篇講述變量的時候,說到變量具備全局做用域和局部做用域。和其餘語言相比,js沒有塊做用域,所以函數中變量的局部做用域在整個函數內部都是可訪問的,而無論是在哪一個代碼塊中。當變量申明時沒有添加var關鍵字,就自動成爲全局做用域變量,而無論它的位置。函數

對象做用域spa

在傳統的面向對象程序設計中,主要關注於公用和私有做用域。公用做用域中的對象屬性能夠從對象外部訪問,即開發者建立對象的實例後,就可以使用它的公用屬性。而私有做用域中的屬性只能在對象內部訪問,即對於外部世界來講,這些屬性並不存在。這意味着若是類定義了私有屬性和方法,則它的子類也不能訪問這些屬性和方法。設計

受保護做用域也是用於定義私有的屬性和方法,只是這些屬性和方法還能被其子類訪問。對象

對 ECMAScript 討論上面這些做用域幾乎毫無心義,由於 ECMAScript 中只存在一種做用域 - 公用做用域。ECMAScript 中的全部對象的全部屬性和方法都是公用的。所以,定義本身的類和對象時,必須格外當心。記住,全部屬性和方法默認都是公用的!ip

建議性的解決方法

許多開發者都在網上提出了有效的屬性做用域模式,解決了 ECMAScript 的這種問題。作用域

因爲缺乏私有做用域,開發者肯定了一個規約,說明哪些屬性和方法應該被看作私有的。這種規約規定在屬性先後加下劃線:開發

obj._color_ = "blue";

這段代碼中,屬性 color 是私有的。注意,下劃線並不改變屬性是公用屬性的事實,它只是告訴其餘開發者,應該把該屬性看做私有的。程序設計

有些開發者還喜歡用單下劃線說明私有成員,例如:obj._color。

做用域鏈

函數對象和其它對象同樣,擁有能夠經過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函數被建立的做用域中對象的集合,這個集合被稱爲函數的做用域鏈,它決定了哪些數據能被函數訪問。

當一個函數建立後,它的做用域鏈會被建立此函數的做用域中可訪問的數據對象填充。若是不是嵌套函數,會被填入一個全局對象,包含有全部全局變量。函數執行時,會建立一個運行時上下文對象,初始化爲當前函數的做用域鏈所包含的對象,組成一個活動對象,添加到做用域鏈之中,這是一個壓棧操做,最近的老是在做用域鏈頭部。函數執行過程當中,每次須要解析變量,都會到做用域鏈中從頭至尾順序查找,直到找到,不然是未定義。

從做用域鏈原來能夠知道,javascript頂層代碼是全局做用域,經過全局對象訪問。對象(包括函數)建立、執行時初始化一個活動對象在做用域鏈頭部,嵌套函數的添加,會將外部函數壓向更深位置。

銅鼓偶做用域鏈的原理,可訪問性是這樣的,javascript頂層代碼只能看到全局對象範圍的變量,對象能夠看到本身和全局變量,嵌套函數能看到本身、外部函數和全局變量,反之則不可見。

相關文章
相關標籤/搜索