Javascript-我對做用鏈、閉包、原型及原型鏈的理解

Javascript-基礎概念總結(2)javascript

     最近學習一些javascript基礎知識,也解決了不少以前的疑惑,記得第一次被問及怎樣理解閉包時,個人回答是:就是相似於封裝吧!如今想一想是有多白癡,學習技術是須要邏輯性很強的,技術注重用事實和數聽說話,每一點都須要理解透徹,在技術上沒有猜想,沒有套路,之後本身在回答技術性的問題時,應作到知道就是知道,不理解或不太明白的,就誠實對待,這樣有助於本身積累知識,瞭解本身的不足,從而提高本身。講了那麼多題外話,是爲了讓本身認識到應真誠的對待學習。下面是一些個人知識總結:前端

【做用域】
javascript中的做用域能夠理解爲一個語句執行的環境大小,有全局的做用域,函數做用域和eval做用域。在JS中沒有塊級做用域。
講到做用域,不得不講執行環境,執行環境在JS中是最爲重要的概念。執行環境定義了變量或函數有權訪問的其餘數據,決定了他們各自的行爲。每一個執行環境都有一個與之關聯的變量對象,環境中定義的全部變量和函數都保存在這個對象中。在web瀏覽器中全局環境被認爲是window對象,某個執行環境中的全部代碼執行完畢後就被該環境銷燬,保存在其中的全部變量和函數定義也隨即銷燬。

每一個函數都有本身的執行環境。當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。而在函數執行以後,棧將其環境彈出,把控制權返回給以前的執行環境。

當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈。做用域鏈的用途是保證對執行環境有權訪問的全部變量和函數的有序訪問。做用域鏈的前端始終是當前執行的代碼所在環境的變量對象。做用域鏈中的下一個變量對象來自包含(外部)環境,在下一個變量對象則來自於在下一個包含環境,這樣一直延續到全局執行環境,全局執行環境的變量對象始終都是做用域鏈中的最後一個對象。

需注意的是:在局部做用域中定義的變量能夠在全局環境和局部環境中交互使用。內部環境能夠經過做用域鏈訪問全部的外部環境,但外部環境不能夠訪問內部環境中的任何變量和函數。每一個環境均可以向上搜索做用域鏈,以查詢變量和函數名,但任何環境都不能夠經過向下搜索做用域鏈而進入另外一個執行環境。

做用域鏈本質上是一個指向變量對象的指針列表,他只引用但不包含變量對象。

【閉包】
閉包是指有權訪問另外一個函數做用域中的變量的函數,這裏要把它與匿名函數區分開(匿名函數:建立一個函數並將它賦值給一個變量,這種狀況下建立的函數叫匿名函數,匿名函數的name屬性是空字符串),建立閉包的常見方式就是在一個函數內部建立另外一個函數。閉包保存的是整個變量的對象。

閉包的做用:在函數執行過程當中,爲讀取和寫入變量的值,就須要在做用域鏈中查找變量,這時靈活方便的閉包就派上用場,咱們知道當一個函數被調用時就會建立一個執行環境及相應的做用域鏈,那麼閉包就會沿着做用域鏈獲取到開發者想要的變量及元素。

注:在維基百科中是這樣定義閉包的:閉包(也稱詞法閉包或函數閉包)是指一個函數或函數的引用,與一個引用環境綁定在一塊兒。這個引用環境是一個存儲該函數每一個非局部變量(也叫自由變量)的表。——閉包不一樣於通常的函數,它容許一個函數在當即詞法做用域外調用時,仍可訪問非本地變量。

閉包靈活方便,也能夠實現封裝,這樣就只能經過對象的特定方法才能訪問到其屬性。可是,不合理的使用閉包會形成空間的浪費,內存的泄露和性能消耗。

【原型和原型鏈】
講到原型鏈,不得不講講用於建立對象的原型模式:咱們建立每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含能夠由特定的全部實例共享的屬性和方法。從字面意思理解,那麼prototype就是經過調用構造函數而建立的那個對象實例的原型對象。使用原型對象的好處是可讓全部對象實例共享它所包含的屬性和方法。咱們能夠經過對象實例訪問保存在原型中的值,但卻不能經過對象實例重寫原型中的值。若是咱們在實例中添加了一個與原型實例中同名的屬性,那麼咱們在實例中建立該屬性,該屬性將會屏蔽原型中的屬性。

不管何時,只要建立一個新函數,就會根據一組特定的規則爲函數建立一個prototype(原型)屬性,這個屬性指向函數的原型對象。

原型鏈:用於實現JS中的實現繼承。(許多語言都支持兩種方式的繼承:接口繼承和實現繼承。接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。因爲函數沒有簽名,在ECMAScriot中只能實現實現繼承。

原型鏈做爲實現繼承的主要方法,其基本思想是利用原型讓一個引用類型繼承另外一個引用繼承的屬性和方法。瞭解一下構造函數、原型和實例的關係:每一個構造函數都是一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。假如咱們讓原型對象等於另外一個類型的實例,那麼此時的原型對象將包含一個指向另外一個原型的指針,相應的另外一個原型中包含着一個指向另外一個構造函數的指針。如此層層遞進,就構成了實例與原型的鏈條。這就是原型鏈的概念。

當函數調用時,需查找和獲取的變量和元素都會經過原型鏈機制一層層的往上搜索在原型對象或繼承來的對象中得到。

java

當函數被建立,就有了做用域,當被調用時,就有了做用域鏈,當被繼承時就有了原型鏈,當須要獲取做用域鏈或原型鏈上的變量或值時,就有了閉包。web

相關文章
相關標籤/搜索