国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javascript面向?qū)ο笾^承(上)

ivyzhang / 955人閱讀

摘要:使用原型鏈實現(xiàn)對原型屬性和方法的繼承,用借用構(gòu)造函數(shù)模式實現(xiàn)對實例屬性的繼承。

我們之前介紹了javascript面向?qū)ο蟮姆庋b的相關內(nèi)容,還介紹了js的call方法,今天開始討論js的繼承
這篇文章參考了《javascript高級程序設計》(第三版),但內(nèi)容不局限于,網(wǎng)上很多關于js繼承的相關內(nèi)容都是來自于這本書,有興趣的同學可以翻閱查看

原型鏈繼承

我們先通過一個栗子,了解一下原型鏈繼承。留意代碼注釋內(nèi)容

//創(chuàng)建自定義構(gòu)造函數(shù)
function Hqg() {
    this.name = "洪七公";
}
//在當前構(gòu)造函數(shù)的原型鏈上添加屬性skill
Hqg.prototype.skill = "打狗棒"

//通過自定義構(gòu)造函數(shù)Hqg實例化一個對象gj
const gj = new Hqg()
console.log(gj.skill);//=>打狗棒
//通過自定義構(gòu)造函數(shù)Hqg實例化一個對象hr
const hr = new Hqg()
console.log(hr.skill);//=>打狗棒

一個簡單的栗子,郭靖和黃蓉都從洪七公那里繼承到了skill 打狗棒,貌似沒什么問題,我們繼續(xù)看demo

//上面代碼省略
const gj = new Hqg()//通過自定義構(gòu)造函數(shù)Hqg實例化一個對象gj
gj.skill = "降龍十八掌"http://重新對gj的skill賦值
console.log(gj.skill);//=>降龍十八掌
//通過自定義構(gòu)造函數(shù)Hqg實例化一個對象hr
const hr = new Hqg()
console.log(hr.skill);//=>打狗棒

對郭靖的skill重新賦值,也沒有影響黃蓉的skill,我們打印一下gj

gj的skill屏蔽掉了原型鏈上的skill,所以gj的skill是降龍十八掌,而hr的skill依然是打狗棒

問題即將暴露
function Hqg() {
    this.name = "洪七公";
}
Hqg.prototype.skill = ["打狗棒"]

const gj = new Hqg()
gj.skill.push ("降龍十八掌")//找到了原型鏈中的skill,并對其執(zhí)行push操作,從而改變了構(gòu)造函數(shù)中的skill屬性
console.log(gj.skill); //=>["打狗棒", "降龍十八掌"]
const hr = new Hqg()
//構(gòu)造函數(shù)中的skill已經(jīng)被改變
console.log(hr.skill); //=>["打狗棒", "降龍十八掌"]

總結(jié)一下,gj和hr都是Hqg的實例,繼承Hqg的屬性和方法,當Hqg的屬性或者方被改變了,后面的實例也會受影響,有時候這并不是我們希望的結(jié)果

借用構(gòu)造函數(shù)

借用?就是使用call或者apply改變一下this指向,
就是子類的構(gòu)造函數(shù)內(nèi)部通過call或者apply調(diào)用父類的構(gòu)造函數(shù),如果對call方法有不了解的地方,可以翻看昨天的文章
舉一個栗子

//創(chuàng)建一個構(gòu)造函數(shù),并添加一些屬性
function Hqg() {
    this.name = "洪七公";
    this.job = "幫主";
    this.skill = ["降龍十八掌", "打狗棒"]
}
//創(chuàng)建一個構(gòu)造函數(shù),并借用了Hqg的構(gòu)造函數(shù)
function Hr() {
        Hqg.call(this)
        this.name = "黃蓉";
        this.job = ["相夫", "教子"]
}
//創(chuàng)建一個構(gòu)造函數(shù),并借用了Hqg的構(gòu)造函數(shù)
function Gj() {
    Hqg.call(this)
    this.name = "郭靖";
    this.job = ["吃飯", "睡覺"]

}
const hr = new Hr();
console.log(hr);

const gj = new Gj();
console.log(gj);

輸出

這樣就避免了原型鏈繼承中,構(gòu)造函數(shù)中的屬性或者方法被其他實例所改變的問題
??:這里要注意call方法的執(zhí)行順序:

//部分代碼省略
function Hr() {
    this.name = "黃蓉";
    this.job = ["相夫", "教子"]
    Hqg.call(this)
}
function Gj() {
    this.name = "郭靖";
    this.job = ["吃飯", "睡覺"]
    Hqg.call(this)
}
//部分代碼省略

如果call在之后執(zhí)行就會導致一個問題

值會被覆蓋,這個要注意!

借用構(gòu)造函數(shù)進行傳參

這個算是一個升級的玩法吧

function Hqg(name,job,skill) {
  this.name = name;
  this.job = job;
  this.skill = skill
}
function Hr() {
  Hqg.call(this,"黃蓉",["相夫", "教子"],["打狗棒"])
}

function Gj() {
  Hqg.call(this,"郭靖",["吃飯", "睡覺"],["降龍十八掌"])
}
const hr = new Hr();
console.log(hr);

const gj = new Gj();
console.log(gj);

輸出

組合繼承

將原型鏈和借用構(gòu)造函數(shù)技術組合到一起。
使用原型鏈實現(xiàn)對原型屬性和方法的繼承,用借用構(gòu)造函數(shù)模式實現(xiàn)對實例屬性的繼承。
這樣既通過在原型上定義方法實現(xiàn)了函數(shù)復用,又能保證每個實例都有自己的屬性
一個栗子

function Hqg(name) {
  this.name = name
  this.skill = ["降龍十八掌","打狗棒"]
}
Hqg.prototype.sayName = function () {
  console.log(this.name);
}
function Hero(name, job) {
  Hqg.call(this, name);
  this.job = job
}
Hero.prototype = new Hqg();
Hero.prototype.constructor = Hero;
Hero.prototype.sayJob = function () {
  console.log(this.job)
}
var gj = new Hero("郭靖", "吃飯睡覺");
gj.skill.push("九陰真經(jīng)");
console.log(gj);
var hr = new Hero("黃蓉", "相夫教子");
console.log(hr);

先看下輸出

我們把這個組合繼承和之前的兩個原型鏈繼承和借用構(gòu)造函數(shù)繼承進行比較
不難發(fā)現(xiàn)組合繼承融合了他們的優(yōu)點,成為javascript中最常用的繼承模式
今天就討論前三個,還有三個明天繼續(xù),不見不散

參考鏈接
你們真的了解JS的繼承嘛?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/100165.html

相關文章

  • javascript面向對象“多態(tài)”

    摘要:之前,本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因為它對于封裝繼承多態(tài)這些面向?qū)ο笳Z言的特點并沒有在語言層面上提供原生的支持。所以在中出現(xiàn)了等關鍵字,解決了面向?qū)ο笾谐霈F(xiàn)了問題。 ES6之前,javascript本質(zhì)上不能算是一門面向?qū)ο蟮木幊陶Z言,因為它對于封裝、繼承、多態(tài)這些面向?qū)ο笳Z言的特點并沒有在語言層面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以讓我們以...

    JerryWangSAP 評論0 收藏0
  • 面向對象JavaScript繼承(一) 類式繼承

    摘要:那你們肯定會問為什么共用,而沒有共用呢,下面就給你解釋,請看引用類型是共用的值類型是私用的。 引言 面向?qū)ο蟮木幊陶Z言都具繼承這一機制,而 JavaScript 是基于原型(Prototype)面向?qū)ο蟪绦蛟O計,所以它的實現(xiàn)方式也是基于原型(Prototype)實現(xiàn)的. 繼承的方式 類式繼承 構(gòu)造函數(shù)繼承 組合繼承 原型式繼承 寄生式繼承 寄生組合式繼承 1.類式繼承 //聲明父...

    forsigner 評論0 收藏0
  • SegmentFault 技術周刊 Vol.32 - 七夕將至,你的“對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評論0 收藏0
  • SegmentFault 技術周刊 Vol.32 - 七夕將至,你的“對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評論0 收藏0
  • SegmentFault 技術周刊 Vol.32 - 七夕將至,你的“對象”還好嗎?

    摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評論0 收藏0
  • JS面向對象的程序設計繼承的實現(xiàn)-組合繼承

    摘要:實現(xiàn)思路使用原型鏈實現(xiàn)對原型方法和方法的繼承,而通過借用構(gòu)造函數(shù)來實現(xiàn)對實例屬性的繼承。繼承屬性繼承方法以上代碼,構(gòu)造函數(shù)定義了兩個屬性和。 JS面向?qū)ο蟮某绦蛟O計之繼承的實現(xiàn)-組合繼承 前言:最近在細讀Javascript高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯誤,會非常感謝您的指出。文中絕大部分內(nèi)容引用自《Java...

    antz 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<