成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端實現繼承的幾種方式

開發 前端
原型鏈的基本構想: 如果原型是另一個類型的實例呢?那就意味著這個原型本身有一個內部指針指向另一個原型,相應地另一個原型也有一個指針指向另一個構造函數。

一、原型鏈繼承

構造函數、原型和實例的關系: 每個構造函數都有一個原型對象,原型有一個屬性指回構造函數,而實例有一個內部指針指向原型。

原型鏈的基本構想: 如果原型是另一個類型的實例呢?那就意味著這個原型本身有一個內部指針指向另一個原型,相應地另一個原型也有一個指針指向另一個構造函數。這樣就在實例和原型之間構造了一條原型鏈。

重點: 讓新實例的原型等于父類的實例。

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
復制代碼

特點:

  1. 實例可繼承的屬性有:實例的構造函數的屬性,父類構造函數屬性,父類原型的屬性。

缺點:

  1. 新實例無法向父類構造函數傳參。
  2. 繼承單一。(只能繼承一個父類構造函數)
  3. 所有新實例都會共享父類實例的屬性。(原型上的屬性是共享的,一個實例修改了原型屬性,另一個實例的原性也會被修改!)
  4. 要想為子類原型新增屬性和方法,必須要在new SuperType()這樣的語句之后執行

代碼如下:

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"
復制代碼

二、借用構造函數繼承

重點: 用.call()和.apply()將父類構造函數引入子類函數(在子類函數中做了父類函數的自執行(復制))

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
復制代碼

特點:

  1. 只繼承了父類構造函數的屬性,沒有繼承父類原型的屬性。
  2. 解決了原型鏈繼承缺點 1、2、3。
  3. 可以繼承多個構造函數屬性(call 多個)。
  4. 在子實例中可向父實例傳參。
  5. 解決了引用值問題

缺點:

  1. 只能繼承父類構造函數的屬性。
  2. 無法實現構造函數的復用。
  3. 每個新實例都有父類構造函數的副本,臃腫。

三、組合繼承(組合原型鏈繼承和借用構造函數繼承)(常用)

重點: 結合了兩種模式的優點,傳參和復用

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.sayAge = function () {
console.log(this.age)
}
let instance1 = new SubType("Nicholas", 29)
console.log("instance1=>", instance1)
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
復制代碼

特點:

  1. 可以繼承父類原型上的屬性,可以傳參,可復用。
  2. 每個新實例引入的構造函數屬性是私有的。

缺點: 組合繼承其實也存在效率問題。最主要的效率問題就是 父類構造函數始終會被調用兩次 :一次在是創建子類原型時調用,另一次是在子類構造函數中調用

四、原型式繼承

重點: 用一個函數包裝一個對象,然后返回這個函數的調用,這個函數就變成了個可以隨意增添屬性的實例或對象。object.create()就是這個原理。

//核心代碼
function object(o) {
function F() {}
F.prototype = o
return new F()
}

let person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"],
}
let anotherPerson = object(person)
anotherPerson.name = "Greg"
anotherPerson.friends.push("Rob")
let yetAnotherPerson = object(person)
yetAnotherPerson.name = "Linda"
yetAnotherPerson.friends.push("Barbie")
console.log(person.friends) // "Shelby,Court,Van,Rob,Barbie"
復制代碼

特點: 類似于復制一個對象,用函數來包裝。

缺點:

  1. 所有實例都會繼承原型上的屬性。
  2. 無法實現復用。(新實例屬性都是后面添加的)

原型式繼承非常適合不需要單獨創建構造函數,但仍然需要在對象間共享信息的場合。但要記住,屬性中包含的引用值始終會在相關對象間共享,跟使用原型模式是一樣的

五、寄生式繼承

重點: 就是給原型式繼承外面套了個殼子。

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

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

let person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"],
}
let anotherPerson = createAnother(person)
anotherPerson.sayHi() // "hi"
//寄生式繼承同樣適合主要關注對象,而不在乎類型和構造函數的場景。object()函數不是寄生式繼承所必需的,任何返回新對象的函數都可以在這里使用。
// 注意 通過寄生式繼承給對象添加函數會導致函數難以重用,與構造函數模式類似。
復制代碼

優點: 沒有創建自定義類型,因為只是套了個殼子返回對象(這個),這個函數順理成章就成了創建的新對象。

缺點: 沒用到原型,無法復用。

六、寄生組合式繼承(常用)

重點: 通過借用構造函數繼承屬性 ,但使用混合式原型鏈繼承方法。基本思路是不通過調用父類構造函數給子類原型賦值,而是取得父類原型的一個副本。說到底就是使用寄生式繼承來繼承父類原型,然后將返回的新對象賦值給子類原型。

寄生: 在函數內返回對象然后調用

組合:

  1. 函數的原型等于另一個實例。
  2. 在函數中用 apply 或者 call 引入另一個構造函數,可傳參
function object(o) {
function F() {}
F.prototype = o
return new F()
}

/*function inheritPrototype(subType, superType) {
let 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 () {
console.log(this.name)
}
function SubType(name, age) {
SuperType.call(this, name)
this.age = age
}
let prototype = object(superType.prototype) // 創建對象
subType.prototype = prototype // 賦值對象
prototype.constructor = subType // 修復實例

//inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function () {
console.log(this.age)
}
復制代碼

優先: 修復了組合繼承的問題

缺點: 實現麻煩

文章出自:??前端餐廳ReTech??,如有轉載本文請聯系前端餐廳ReTech今日頭條號。

github:??https://github.com/zuopf769??

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2010-02-06 14:12:54

C++繼承方式

2021-10-07 20:36:45

Redis集群場景

2010-08-05 09:39:17

Flex頁面跳轉

2023-10-30 11:53:37

繼承JS父類

2024-05-10 07:44:23

C#進程程序

2023-05-07 07:56:53

Python方式

2022-11-03 15:22:15

數據結構Python

2021-05-27 08:21:51

JS繼承對象

2021-05-07 16:19:36

異步編程Java線程

2010-09-25 14:48:55

SQL連接

2021-01-19 11:56:19

Python開發語言

2009-05-13 11:50:17

C#多繼承接口

2022-03-28 20:57:31

私有屬性class屬性和方法

2022-02-17 08:20:17

Spring執行代碼SpringBoot

2025-01-21 10:04:40

Java并發阻塞隊列

2010-11-24 09:56:20

mysql拷貝表

2021-08-02 11:13:28

人工智能機器學習技術

2023-09-07 13:21:00

Linux軟件

2021-06-16 07:02:22

Python方式郵件

2011-03-10 14:19:56

JavaScript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧洲高清转码区一二区 | 国产精品一区二区三级 | 国产一二三区在线 | 国产一区二区三区久久 | 久久久久久久电影 | 日韩在线小视频 | 国产色婷婷精品综合在线手机播放 | 欧美日韩亚洲一区 | 日产精品久久久一区二区福利 | 欧美日韩国产高清 | 国产成人精品免费视频大全最热 | 日韩2020狼一二三 | 天天干夜夜操 | 日韩影院在线观看 | 精品国产亚洲一区二区三区大结局 | 欧美一级大片免费观看 | 日韩伦理一区二区 | 久久亚洲二区 | 精品国产综合 | 九九热精品视频 | 日韩av免费在线观看 | 国产女人与拘做视频免费 | 蜜桃精品噜噜噜成人av | 日韩高清一区 | 日韩中文一区二区三区 | 中文字幕一区二区不卡 | 国产一区欧美 | 有码在线| 亚洲欧美日韩在线不卡 | 中文字幕视频在线免费 | 鲁视频 | 在线视频a | 欧美美女被c | 神马久久久久久久久久 | 黄色香蕉视频在线观看 | 欧美三级电影在线播放 | 成人亚洲片 | 亚洲性视频网站 | 国产亚洲精品久久久久动 | 日韩无| 男女污网站 |