原型鏈以及繼承的幾種方式

来源:https://www.cnblogs.com/8609lql/archive/2019/03/21/10572518.html
-Advertisement-
Play Games

學習原型鏈前需要瞭解 使用構造函數模式創建的對象實例,都有一個constructor(構造函數) 屬性,該屬性指向構造函數。 function Person (name, age, job) { this.name = name; this.age = age; this.job = job; th ...


學習原型鏈前需要瞭解

使用構造函數模式創建的對象實例,都有一個constructor(構造函數) 屬性,該屬性指向構造函數。

function Person (name, age, job) {

  this.name = name;

  this.age = age;

  this.job = job;

  this.sayName = function () {

    alert(this.name)

  }

}

var person1 = new Person(“Nicholas”, 29, “Sofware Engineer”)

var person2 = new Person(“Greg”, 27, “Doctor”)

alert(person1.constructor == Person) // true

alert(person2.constructor == Person) // true

//創建出來的所有對象即使Object的實例,同時也是Person的實例

只要創建一個新函數,就會根據特定的規則為該函數創建一個 prototype 屬性,這個屬性是一個指針,指向一個對象。這個對象的用途是包含可以由特定類型的 所有實例 共用的屬性和方法,這個對象就是通過調用構造函數創建的對象實例的原型對象。

原型鏈
構造函數,原型和實例的關係
每一個構造函數都有一個原型對象,原型對象包含一個指向構造函數的指針,而每個實例都包含一個指向構造函數的原型對象的內部指針

原型鏈
如果讓一個原型對象等於另一個類型的實例,層層遞進,構成實例與原型的鏈條,這就是原型鏈

創建了自定義的構造函數,其原型對象預設只會取得 constructor 屬性;其他方法都是從Object 繼承來的
當調用構造函數創建一個實例之後,該實例內部會包含一個指針(屬性),指向構造函數的原型,我們可以稱這個指針為 [[Prototype]]

Function(Object)包含 prototype(原型對象指針)
prototype(原型對象指針)包含constructor(構造函數)屬性
constructor(構造函數)屬性包含指向原型對象所在函數的指針

繼承的幾種方式

js主要是通過原型鏈實現繼承,原型鏈的構建是通過將一個類型的實例賦值給另外一個構造函數的原型實現的

原型鏈繼承

基本代碼

function SuperType () {
  this.property = true
}
SuperType.prototype.getSuperValue = function () {
  return this.property
}
function SubType () {
  this.subproperty = false
}
// 繼承了SuperType //
SubType.prototype = new SuperType()
SubType.protype.getSubValue = function () {
  return this.subproperty
}
var instance = new SubType()

實現的本質:重寫原型對象,用一個新的類型的實例去替代

SubType Prototype === SuperType構造函數的實例
註意:
1.預設的原型
所有的引用類型都預設繼承Object,這個繼承也是通過原型鏈實現的

2.原型鏈的問題
a.對象實例共用所有繼承的屬性和方法
b.創建子類型的實例的時候,不能傳遞參數

借用構造函數繼承

基本代碼

function SuperType () {
  this.colors = ["red", "blue", "green"]
}
function SubType () {
  // 繼承了SuperType
  SuperType.call(this)
  // 只能繼承構造函數上的屬性
}

實現的本質:在子類構造函數的內部調用超類型構造函數,使用aapply()和call() 方法
註意:
1.函數復用性不高
2.只能繼承實例上的屬性,原型上的方法不可見

組合繼承(偽經典繼承)

基本代碼

function SuperType (name) {
  this.name = name
  this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function () {
  alert(this.name)
}
function SubType (name, age) {
  // 繼承屬性
  SuperType.call(this, name) // 第二次調用SuperType()
  this.age = age
}
//繼承方法
SubType.prototype = new SuperType() // 第一次調用 SuperType()
Subtype.prototype.sayAge = function () {
  alert(this.age)
}

實現思路:使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數來實現對實例屬性的繼承
註意:
組合繼承避免了原型鏈和借用構造函數的缺陷,融合了他們的優點,成為js中最常用的繼承方式。

原型式繼承

基本代碼

function object (o) {
  function F(){}
  F.prototype = o
  return new F()
}

實現本質:object()函數對傳入其中的對象執行了一次淺複製
註意:
可以在不必預先定義構造函數的情況下實現繼承,其本質是執行對給定對象的淺複製,而複製的副本還可以得到進一步的改造
問題還是包含引用類型的屬性都會被共用

寄生式繼承

基本代碼

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

實現本質和寄生構造函數還有工廠模式類似
註意:
基於某個對象或者某些信息創建一個對象,然後增強對象,最後返回對象,為瞭解決組合繼承模式由於多次調用超類型構造函數而導致的低效率問題,可以將這個模式與組合繼承一起使用

寄生組合式繼承

基本代碼

function inheritPrototype (subType, superType) {
  var prototype = object(superType.prototype) // 創建對象
  prototype.constructor = subType // 增強對象
  subType.prototype = prototype // 指定對象
}

function SuperType (name) {
  this.name = name
  this.colors = {"red", "blue", "green"}
}
SuperType.prototype.sayName = function () {
  alert(this.name)
}
function SubType (name, age) {
SuperType.call(this, name)
  this.age = age
}
inheritPrototype(SubType, SuperType)

 

實現本質:借用構造函數來繼承屬性,通過原型鏈的混成形式來繼承方法
註意:
高效率只調用了一次構造函數,集寄生式繼承和組合繼承的優點於一身,是實現基於類型繼承的最有效方式

小結:
JavaScript主要通過原型鏈實現繼承。原型鏈的構建是通過將一個類型的實例賦值給另一個構造函數的原型實現的。
使用最多的繼承模式是組合繼承,這種模式使用原型鏈繼承共用的屬性和方法,通過借用構造函數繼承實例屬性

註:博客新手,文章有誤請大家指出,不勝感激

說實話,博客園的編輯器是有點難用

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Vue腳手架的搭建步驟 1. 去node.js官網下載node.js並安裝,如下圖: 2. 找到下載的文件並點擊安裝: 一直到finish完成。安裝成功 3. 通過DOS密令打開: 輸入:node –v回車 可以查看安裝node.js 版本號如下圖: 4. 使用淘寶NPM鏡像:下圖 5. 進入下圖頁 ...
  • 運算符 數學運算符的正統,number和number的數學運算,結果是number。出於面試的考慮,有一些奇奇怪怪的數學運算: 數學運算中:只有純字元串、布爾值、null能夠進行隱式轉換。 不純的字元串和undefined是不能進行隱式轉換,結構都是NaN: 加法比較特殊,因為“+”號同時是加法和拼 ...
  • columns(列) 和 rows(行) 為了使其成為二維的網格容器,我們需要定義列和行。讓我們創建3列和2行。我們將使用grid-template-row和grid-template-column屬性。 grid-template-columns的3個值表示三列,相應的數值表示列寬即都為100px ...
  • 報錯信息: Symbol.iterator is not a function [duplicate] 代碼示例: 分析原因: DOM獲取的nodeList類似數組,但是不是數組,直接用for of迴圈確實可以遍歷,但是在iphone5下回報錯,所以需要轉為真正的數組。 解決方案: 如上面代碼,加了 ...
  • 事件冒泡 :當一個元素接收到事件的時候 會把他接收到的事件傳給自己的父級,一直到window 。 html代碼: 代碼很簡單,就是三個父子關係的div,然後分別加了點擊事件,當我們在div3裡面點擊的時候,會發現彈出了一次3,接著又彈出了2,最後又彈出了1,這說明點擊的時候,不僅div3的事件被觸發 ...
  • vue 腳手架 立即可以寫業務 ...
  • https://github.com/cynthiawupore/wq-cli ...
  • 2019-03-21 16:05:45 周期:5天 學習資料:http://how2j.cn/k/css2/css2-tutorial/238.html?p=67889 源代碼地址 GitHub:https://github.com/BenCoper/CSS Readme:簡要概括知識點詳細代碼前往 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...