JavaScript高級程序設計(第四版)--學習記錄之對象、類和面向對象編程(中)

創建對象方式

工廠模式:用于抽象創建特定對象的過程。可以解決創建多個類似對象的問題,但沒有解決對象標識問題。(即新創建的對象是什么類型)

function createPerson(name, age, job) { let o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function() { console.log(this.name); }; return o; 
} 
let person1 = createPerson("Nicholas", 29, "Software Engineer"); 
let person2 = createPerson("Greg", 27, "Doctor");

構造函數模式:用于創建特定類型對象。構造函數名稱的首字母都是要大寫的,用來區分非構造函數。

function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function() { console.log(this.name); }; 
} 
let person1 = new Person("Nicholas", 29, "Software Engineer"); 
let person2 = new Person("Greg", 27, "Doctor"); 
person1.sayName(); // Nicholas 
person2.sayName(); // Greg

原型模式:每個函數都會創建一個prototype屬性,這個屬性是一個對象,包含應該由特定引用類型的實例共享的屬性和方法。使用原型對象的好處是,在它上面定義的屬性和方法可以被對象實例共享。

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { console.log(this.name); 
}; 
let person1 = new Person(); 
person1.sayName(); // "Nicholas" 
let person2 = new Person(); 
person2.sayName(); // "Nicholas" 
console.log(person1.sayName == person2.sayName); // true

繼承的方式:接口繼承和實現繼承。接口繼承在 ECMAScript 中是不可能的,因為函數沒有簽名。實現繼承是 ECMAScript 唯一支持的繼承方式,而這主要是通過原型鏈實現的。

原型鏈?

其基本思想就是通過原型繼承多個引用類型的屬性和方法。
function SuperType() { this.property = true; 
} 
SuperType.prototype.getSuperValue = function() { return this.property; 
}; 
function SubType() { this.subproperty = false; 
} 
// 繼承 SuperType 
SubType.prototype = new SuperType(); 
SubType.prototype.getSubValue = function () {
return this.subproperty; 
}; 
let instance = new SubType(); 
console.log(instance.getSuperValue()); // true

原型鏈雖然是實現繼承的強大工具,但它也有問題。問題一:出現在原型中包含引用值的時候。前面在談到原型的問題時也提到過,原型中包含的引用值會在所有實例間共享,這也是為什么屬性通常會在構造函數中定義而不會定義在原型上的原因。在使用原型實現繼承時,原型實際上變成了另一個類型的實例。這意味著原先的實例屬性搖身一變成為了原型屬性。
問題二:子類型在實例化時不能給父類型的構造函數傳參。
function SuperType() { this.colors = ["red", "blue", "green"]; 
} 
function SubType() {} 
// 繼承 SuperType 
SubType.prototype = new SuperType(); 
let instance1 = new SubType(); 
instance1.colors.push("black"); 
console.log(instance1.colors); // "red,blue,green,black" 
let instance2 = new SubType(); 
console.log(instance2.colors); // "red,blue,green,black"

解決原型包含引用值導致的繼承問題

盜用構造函數:在子類構造函數中調用父類構造函數。優點可以在子類構造函數中向父類構造函數傳參。缺點:必須在構造函數中定義方法,因此函數不能重用。

function SuperType(name){ this.name = name; 
} 
function SubType() { // 繼承 SuperType 并傳參SuperType.call(this, "Nicholas"); // 實例屬性this.age = 29; 
} 
let instance = new SubType(); 
console.log(instance.name); // "Nicholas"; 
console.log(instance.age); // 29

?組合繼承:綜合了原型鏈和盜用構造函數,使用原型鏈繼承原型上的屬性和方法,通過盜用構造函數繼承實例屬性。

function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function() { console.log(this.name); 
}; 
function SubType(name, age){ // 繼承屬性SuperType.call(this, name); this.age = age; 
} 
// 繼承方法
SubType.prototype = new SuperType(); 
SubType.prototype.sayAge = function() { console.log(this.age); 
}; 
let instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
console.log(instance1.colors); // "red,blue,green,black" 
instance1.sayName(); // "Nicholas"; 
instance1.sayAge(); // 29 
let instance2 = new SubType("Greg", 27); 
console.log(instance2.colors); // "red,blue,green" 
instance2.sayName(); // "Greg"; 
instance2.sayAge(); // 27

原型式繼承

ES5通過增加 Object.create()方法將原型式繼承的概念規范化了,這個方法接收兩個

參數:作為新對象原型的對象,以及給新對象定義額外屬性的對象(第二個可選)。
原型式繼承非常適合不需要單獨創建構造函數,但仍然需要在對象間共享信息的場合。
let person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] 
}; 
let anotherPerson = Object.create(person); 
anotherPerson.name = "Greg"; 
anotherPerson.friends.push("Rob"); 
let yetAnotherPerson = Object.create(person); 
yetAnotherPerson.name = "Linda"; 
yetAnotherPerson.friends.push("Barbie"); 
console.log(person.friends); // "Shelby,Court,Van,Rob,Barbie"

寄生式繼承

function createAnother(original){ let clone = object(original); // 通過調用函數創建一個新對象clone.sayHi = function() { // 以某種方式增強這個對象console.log("hi"); }; return clone; // 返回這個對象
}

寄生式組合繼承

function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function() { console.log(this.name); 
}; 
function SubType(name, age){ SuperType.call(this, name); // 第二次調用 SuperType() this.age = age; 
} 
SubType.prototype = new SuperType(); // 第一次調用 SuperType() 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function() { console.log(this.age); 
};

寄生式組合繼承算是引用類型繼承的最佳模式!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39294.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39294.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39294.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android:移動垃圾軟件

講解政策相關,最近升級AI掃蕩系統和證書防高風險,回復按留言時間來排,請耐心等待 移動垃圾軟件 官方政策公告行為透明、信息披露清晰保護用戶數據不要損害移動體驗軟件準則反垃圾軟件政策Google API 服務用戶數據政策官方政策公告 ? 在 Google,我們相信,如果我們關注用戶…

oracle創建用戶和賦權

在 Oracle 數據庫中,要創建一個用戶并授予權限,可以按照以下步驟進行操作:步驟一:創建用戶 sql CREATE USER yonghuming IDENTIFIED BY 123456; 這里將 yonghuming 替換為要創建的用戶名,123456 替換為用戶的密碼。步…

Retrofit源碼閱讀

動態代理在 Android 中的應用:Retrofit 源碼解析 在之前的文章 《Andriod 網絡框架 OkHttp 源碼解析》 中我們分析了 OkHttp 的源代碼。現在我們就來分析一下 OkHttp 的兄弟框架 Retrofit。關于 Retrofit 的注解的使用,可以參考其官方文檔:h…

控制臺廠商配額查詢

概述 廠商推送限制 每個廠商通道都有對應的廠商配額和 QPS 限制,當請求超過限制且已配置廠商回執時,MobPush會采取以下措施: 當開發者推送請求超過廠商配額時,MobPush將通過自有通道進行消息下發。當開發者推送請求超過廠商 QPS…

java default注解怎么設置數組默認值

在Java中,為注解的數組類型屬性設置默認值時,需要使用大括號{}包圍數組元素。如果數組默認值只有一個元素,也可以直接使用該元素而不需要大括號。下面是一個示例,展示了如何為注解的數組類型屬性設置默認值: import j…

Spark on k8s 源碼解析執行流程

Spark on k8s 源碼解析執行流程 1.通過spark-submit腳本提交spark程序 在spark-submit腳本里面執行了SparkSubmit類的main方法 2.運行SparkSubmit類的main方法,解析spark參數,調用submit方法 3.在submit方法里調用doRunMain方法,最終調用r…

Activity top resumed state loss timeout for ActivityRecord 報錯原因是?

Activity top resumed state loss timeout for ActivityRecord 這個錯誤通常不是直接顯示給用戶看的,而是Android系統內部日志(如Logcat)中的一個錯誤信息,它指示了系統在嘗試恢復或管理某個Activity的狀態時遇到了問題。這個錯誤…

算法-位圖與底層運算邏輯

文章目錄 1. 位圖的理論基礎2. 完整版位圖實現3. 底層的運算邏輯-位運算 1. 位圖的理論基礎 首先我們要理解什么是位圖, 位圖的一些作用是什么 位圖法就是bitmap的縮寫。所謂bitmap,就是用每一位來存放某種狀態,適用于大規模數據,但數據狀態又…

Python+Pytest+Allure+Yaml+Pymysql+Jenkins+GitLab接口自動化測試框架詳解

PythonPytestAllureYaml接口自動化測試框架詳解 編撰人:CesareCheung 更新時間:2024.06.20 一、技術棧 PythonPytestAllureYamlJenkinsGitLab 版本要求:Python3.7.0,Pytest7.4.4,Allure2.18.1,PyYaml6.0 二、環境配置 安裝python3.7&…

Python 類與對象:深入理解與應用

在 Python 中,類是一種抽象數據類型,用于描述具有相同屬性和方法的對象集合。類通過屬性(變量)和方法(函數)來定義對象的行為。對象是類的實例化結果,它可以具備類定義的所有特性。Python 中的類…

ROS2 RQT

1. RQT是什么 RQT是一個GUI框架,通過插件的方式實現了各種各樣的界面工具。 強行解讀下:RQT就像插座,任何電器只要符合插座的型號就可以插上去工作。 2.選擇插件 這里我們可以選擇現有的幾個RQT插件來試一試,可以看到和話題、參…

金蝶云星空字段之間連續觸發值更新

文章目錄 金蝶云星空字段之間連續觸發值更新場景說明具體需求:解決方案 金蝶云星空字段之間連續觸發值更新 場景說明 字段A配置了字段B的計算公式,字段B配置了自動C的計算公式,修改A的時候,觸發了B的重算,但是C觸發不…

【云原生】Kubernetes----ETCD數據的備份與恢復

目錄 引言 一、ETCD數據備份 (一)確定備份策略 (二)使用etcdctl工具進行備份 1.安裝etcdctl命令 2.設置ETCDCTL_API環境變量 (三)執行備份 二、數據還原 (一)創建新資源 &…

XMind2TestCase:高效測試用例設計工具

XMind2TestCase:高效測試用例設計工具 引言傳統測試用例設計的問題1. Excel表格的局限性2. 傳統測試管理工具的不足3. 自研測試管理工具的挑戰 思維導圖在測試用例設計中的應用思維導圖的優勢思維導圖的挑戰 簡介安裝使用方式命令行調用使用Web界面 使用示例XMind文…

廣州自閉癥機構哪家好

在廣州,眾多的自閉癥康復機構中,星貝育園自閉癥兒童康復學校以其獨特的優勢脫穎而出。 一、專業的師資團隊 我們擁有一支經驗豐富、專業素養極高的師資隊伍。每位老師都經過嚴格的專業培訓,深入了解自閉癥兒童的特點和需求。他們不僅…

蒼穹外賣項目 常用注解 + 動態sql

常用注解 常見的注解解析方法有兩種: 編譯期直接掃描:編譯器在編譯 Java 代碼的時候掃描對應的注解并處理,比如某個方法使用Override 注解,編譯器在編譯的時候就會檢測當前的方法是否重寫了父類對應的方法。運行期通過反射處理&…

SAP_ABAP相關日語單詞

基本概念 1. プログラミング言語 (プログラミングげんご, Puroguramingu gengo) - 編程語言 2. 開発 (かいはつ, Kaihatsu) - 開發 3. システム (システム, Shisutemu) - 系統 4. モジュール (モジュール, Mojūru) - 模塊 5. トランザクションコード (トランザクションコード,…

探索旅游卡項目的八大黃金賽道,你離月入十幾萬僅一步之遙!

作為旅游卡項目的推廣精英,我深知在這個充滿機遇與挑戰的時代,選擇正確的賽道至關重要。今天,我將從定位、內容、產品、流量、變現這五個核心維度出發,為你揭秘旅游卡項目的八大熱門方向。如果你正對旅游充滿熱情,或擁…

【基于R語言群體遺傳學】-3-計算等位基因頻率

書接上文,我們講完了哈代溫伯格基因型頻率,也使用數據進行了擬合,那么接下來就是考慮一些計算的問題: 【基于R語言群體遺傳學】-1-哈代溫伯格基因型比例-CSDN博客 【基于R語言群體遺傳學】-2-模擬基因型(simulating …

【leetcode--最小棧】

設計一個支持 push ,pop ,top 操作,并能在常數時間內檢索到最小元素的棧。 實現 MinStack 類: MinStack() 初始化堆棧對象。void push(int val) 將元素val推入堆棧。void pop() 刪除堆棧頂部的元素。int top() 獲取堆棧頂部的元素。int get…