【JavaScript核心技術卷】JS的邏輯內存模型

JavaScript的邏輯內存模型

Java語言是面向對象的,而JavaScript語言是基於對象的。兩者之間是有差異的。這裏主要以這兩種語言進行一個對比。

一、面向對象的三要素

1.封裝 (數據結構 + 算法)

  • Java語言可通過訪問修飾符來保證封裝性:private。
    該類的實例狀態應該只能由該類的方法訪問修改,否則我們說該類的封裝性遭到了破壞。封裝性保證了安全和可維護。
    JavaScript語言不支持訪問權限修飾符,無法隱藏具體實現。

  • JavaScript語言是動態成員, Java語言靜態成員。

  • JS中只有實方法(含有隱式形參this)。沒有靜態方法。

  • JS沒有函數重載,形參只是用於便利存取實參。

2.繼承

  • Java語言只支持靜態繼承。JavaScript語言支持動態繼承。

3.多態

  • 多態的前提是繼承和虛方法。Java語言支持多態。JavaScript語言無虛函數,所以不支持多態。

我們知道Java語言中有接口類和抽象類,存在接口類和抽象類的繼承。而JavaScript語言中無接口類和抽象類。

JavaScript堆中只有對象一種數據結構(一般是哈希表結構),而Java堆中有實例和類兩種數據結構。所以,JavaScript是一切皆爲對象。

二、JavaScript的邏輯內存模型

邏輯內存模型由執行模型和對象模型組成。
在這裏插入圖片描述

JavaScript的邏輯內存模型是比較複雜的。

執行模型

可執行的JavaScript代碼分三種類型:

  1. Global Code,即全局的、不在任何函數裏面的代碼,例如:一個js文件、嵌入在HTML頁面中的js代碼等。
  2. Eval Code,即使用eval()函數動態執行的JS代碼。
  3. Function Code,即用戶自定義函數中的函數體JS代碼。 不同類型的JavaScript代碼具有不同的Execution Context

在一個頁面中,第一次載入JS代碼時創建一個全局執行環境,當調用一個 JavaScript 函數時,該函數就會進入相應的執行環境。如果又調用了另外一個函數(或者遞歸地調用同一個函數),則又會創建一個新的執行環境,並且在函數調用期間執行過程都處於該環境中。當調用的函數返回後,執行過程會返回原始執行環境。因而,運行中的 JavaScript 代碼就構成了一個執行環境棧。執行模型就是對JS代碼執行環境的一個描述

對象模型

JS中一切皆對象,對象模型就是對代碼中對象以及對象之間關係的一種抽象描述

對象中的[[]]屬性是內置的隱式屬性,有JS引擎添加

  1. 內部隱式屬性[[Class]]的值爲”Function”,說明該函數對象的類名稱是”Function”
  2. 內部隱式屬性[[Extensible]] 的值爲 true,說明該函數對象的屬性可以增刪
  3. 內部隱式屬性[[Prototype]]爲Function .prototype,說明該函數對象是類Function的實例
  4. 內部隱式屬性[[Call]],它是由用戶JS代碼實現的用戶方法
  5. 內部隱式屬性[[Construct]],它是由JS引擎用native code 或內置JS代碼實現的內部方法
  6. 內部隱式屬性[[Scope]]設置函數對象的作用域鏈:
  • 用function關鍵字聲明的函數聲明語句創建的函數對象,其[[Scope]]靜態作用域鏈複製當前執行環境的執行作用域鏈
  • 使用function關鍵字聲明的匿名函數表達式創建的函數對象,其[[Scope]]靜態作用域鏈複製當前執行環境的作用域鏈
  • 使用function關鍵字聲明的命名函數表達式創建的函數對象,其[[Scope]]靜態作用域鏈複製當前執行環境的作用域鏈;在[[Scope]]靜態作用域鏈的前端添加一個Object類的實例;在該實例上添加一個屬性,名字爲函數名functionName,值爲返回的函數對象fn。
	var test = function functionName(a){document.write(a + "<br />");}
  • new Function()、Function()函數創建的函數對象的[[Scope]]靜態作用域鏈永遠複製全局執行環境的作用域鏈,只包含window對象。
var fn = new Function("形式參數1","形式參數2",...,"形式參數n","函數體");
var fn = Function("形式參數1","形式參數2",...,"形式參數n","函數體");

我們和Java的對比一下:
在這裏插入圖片描述

三、JavaScript的對象與Java的實例

在這裏插入圖片描述
中括號內放置的是引擎給加的隱式屬性,必包括3個(Prototype指針,Class字符串/類名,Extensible/屬性是否可增刪),只包括這三個隱式屬性的是對象

四、window對象的內存邏輯模型

與全局執行環境對象關聯的變量對象(Variable Object)在JS中稱爲全局對象(Global Object),JS規定其一定是一個宿主對象,在Web中,爲window對象。我們編寫的JS代碼可以訪問window對象。全局執行環境直到應用程序退出—例如關閉網頁或瀏覽器—時纔會被銷燬。相當於Java的常量池。
在這裏插入圖片描述

與全局執行環境對象關聯的變量對象(Variable Object)在JS中稱爲全局對象(Global Object),JS規定其一定是一個宿主對象,在Web中,爲window對象。我們編寫的JS代碼可以訪問window對象。全局執行環境直到應用程序退出—例如關閉網頁或瀏覽器—時纔會被銷燬。相當於Java的常量池

五、Object構造函數的內存邏輯模型

相當於Java中的Object類。有兩個對象結構組成。
在這裏插入圖片描述

原型對象中的方法和屬性都是可以被繼承的 類對象中放置的都是靜態屬性,可以直接通過類調用 可以根據constructor屬性區分類對象與原型對象:原型對象有constructor屬性,沒有prototype屬性,類對象則相反

六、Function構造函數的內存邏輯模型

相當於Java中的Class反射類。有兩個對象結構組成。

在這裏插入圖片描述

JS中一切皆對象,所以Function也是Object的實例,Function.prototype指向Object的原型

七、JavaScript的類繼承

在這裏插入圖片描述

繼承的實質是指JS對象的原型指向其父類

八、JavaScript的對象與類

在這裏插入圖片描述

JS的原型對象+類對象相當於java的類

Thanks for 【進階er】’ help

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章