真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

javascript繼承的作用是什么

今天小編給大家分享一下javascript繼承的作用是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

霸州ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!

javascript繼承的作用:1、可以不調(diào)用“父類(lèi)”的構(gòu)造方法就創(chuàng)造新的實(shí)例;2、修改“父類(lèi)”的prototype可以動(dòng)態(tài)修改所有已經(jīng)創(chuàng)造的實(shí)例;3、可以動(dòng)態(tài)修改一個(gè)對(duì)象的原型。

本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

JavaScript 是以對(duì)象為基礎(chǔ),以函數(shù)為模型,以原型為繼承的面向?qū)ο箝_(kāi)發(fā)模式。

javascript繼承的作用:

1、可以不調(diào)用「父類(lèi)」的構(gòu)造方法就創(chuàng)造新的實(shí)例

2、修改「父類(lèi)」的 prototype 可以動(dòng)態(tài)修改所有已經(jīng)創(chuàng)造的實(shí)例

3、可以動(dòng)態(tài)修改一個(gè)對(duì)象的原型,也就是說(shuō)爹媽可以換

下面介紹定義 JavaScript 類(lèi)型的方法,以及實(shí)現(xiàn)繼承的常用模式。

構(gòu)造原型

直接使用 prototype 原型設(shè)計(jì)類(lèi)的繼承存在兩個(gè)問(wèn)題。

由于構(gòu)造函數(shù)事先聲明,而原型屬性在類(lèi)結(jié)構(gòu)聲明之后才被定義,因此無(wú)法通過(guò)構(gòu)造函數(shù)向原型動(dòng)態(tài)傳遞參數(shù)。這樣實(shí)例化對(duì)象都是一個(gè)模樣,沒(méi)有個(gè)性。要改變?cè)蛯傩灾?,則所有實(shí)例都會(huì)受到干擾。

當(dāng)原型屬性的值為引用類(lèi)型數(shù)據(jù)時(shí),如果在一個(gè)對(duì)象實(shí)例中修改該屬性值,將會(huì)影響所有的實(shí)例。

示例1

簡(jiǎn)單定義 Book 類(lèi)型,然后實(shí)例化。

function Book () {};  //聲明構(gòu)造函數(shù)
Book.prototype.o = {x : 1, y : 2};  //構(gòu)造函數(shù)的原型屬性o是一個(gè)對(duì)象
var book1 = new Book ();  //實(shí)例化對(duì)象book1
var book2 = new Book ();  //實(shí)例化對(duì)象book2
console.log(book1.o.x);  //返回1
console.log(book2.o.x);  //返回1
book2.o.x = 3;  //修改實(shí)例化對(duì)象book2中的屬性x的值
console.log(book1.o.x);  //返回3
console.log(book2.o.x);  //返回3

由于原型屬性 o 為一個(gè)引用型的值,所以所有實(shí)例的屬性 o 的值都是同一個(gè)對(duì)象的引用,一旦 o 的值發(fā)生變化,將會(huì)影響所有實(shí)例。

構(gòu)造原型正是為了解決原型模式而誕生的一種混合設(shè)計(jì)模式,它把構(gòu)造函數(shù)模式與原型模式混合使用,從而避免了上述問(wèn)題的發(fā)生。

實(shí)現(xiàn)方法:對(duì)于可能會(huì)相互影響的原型屬性,并且希望動(dòng)態(tài)傳遞參數(shù)的屬性,可以把它們獨(dú)立出來(lái)使用構(gòu)造函數(shù)模式進(jìn)行設(shè)計(jì)。對(duì)于不需要個(gè)性設(shè)計(jì)、具有共性的方法或?qū)傩?,則可以使用原型模式來(lái)設(shè)計(jì)。

示例2

遵循上述設(shè)計(jì)原則,把其中兩個(gè)屬性設(shè)計(jì)為構(gòu)造函數(shù)模式,設(shè)計(jì)方法為原型模式。

function Book (title, pages) {  //構(gòu)造函數(shù)模式設(shè)計(jì)
    this.title = title;
    this.pages = pages;
}
Book.prototype.what = function () {  //原型模式設(shè)計(jì)
    console.log(this.title + this.pages);
};
var book1 = new Book("JavaScript 程序設(shè)計(jì)", 160);
var book2 = new Book("C語(yǔ)言程序設(shè)計(jì)", 240);
console.log(book1.title);
console.log(book2.title);

構(gòu)造原型模式是 ECMAScript 定義類(lèi)的推薦標(biāo)準(zhǔn)。一般建議使用構(gòu)造函數(shù)模式定義所有屬性,使用原型模式定義所有方法。這樣所有方法都只創(chuàng)建一次,而每個(gè)實(shí)例都能夠根據(jù)需要設(shè)置屬性值。這也是使用最廣的一種設(shè)計(jì)模式。

動(dòng)態(tài)原型

根據(jù)面向?qū)ο蟮脑O(shè)計(jì)原則,類(lèi)型的所有成員應(yīng)該都被封裝在類(lèi)結(jié)構(gòu)體內(nèi)。例如:

function Book (title, pages) {  //構(gòu)造函數(shù)模式設(shè)計(jì)
    this.title = title;
    this.pages = pages;
    Book.prototype.what = function () {  //原型模式設(shè)計(jì),位于類(lèi)的內(nèi)部
        console.log(this.title + this.pages);
    };
}

但當(dāng)每次實(shí)例化時(shí),類(lèi) Book 中包含的原型方法就會(huì)被重復(fù)創(chuàng)建,生成大量的原型方法,浪費(fèi)系統(tǒng)資源??梢允褂?if 判斷原型方法是否存在,如果存在就不再創(chuàng)建該方法,否則就創(chuàng)建方法。

function Book (title, pages) {
    this.title = title;
    this.pages = pages;
    if (typeof Book.isLock == "undefined") {  //創(chuàng)建原型方法的鎖,如果不存在則創(chuàng)建
        Book.prototype.what = function () {
            console.log(this.title + this.pages);
        };
        Book.isLock = true;  //創(chuàng)建原型方法后,把鎖鎖上,避免重復(fù)創(chuàng)建
    }
}
var book1 = new Book("JavaScript 程序設(shè)計(jì)", 160);
var book2 = new Book("C語(yǔ)言程序設(shè)計(jì)", 240);
console.log(book1.title);
console.log(book2.title);

typeof Book.isLock 表達(dá)式能夠檢測(cè)該屬性值的類(lèi)型,如果返回為 undefined 字符串,則不存在該屬性值,說(shuō)明沒(méi)有創(chuàng)建原型方法,并允許創(chuàng)建原型方法,設(shè)置該屬性的值為 true,這樣就不用重復(fù)創(chuàng)建原型方法。這里使用類(lèi)名 Book,而沒(méi)有使用 this,這是因?yàn)樵褪菍儆陬?lèi)本身的,而不是對(duì)象實(shí)例的。

動(dòng)態(tài)原型模式與構(gòu)造原型模式在性能上是等價(jià)的,用戶(hù)可以自由選擇,不過(guò)構(gòu)造原型模式應(yīng)用比較廣泛。

工廠模式

工廠模式是定義類(lèi)型的最基本方法,也是 JavaScript 最常用的一種開(kāi)發(fā)模式。它把對(duì)象實(shí)例化簡(jiǎn)單封裝在一個(gè)函數(shù)中,然后通過(guò)調(diào)用函數(shù),實(shí)現(xiàn)快速、批量生產(chǎn)實(shí)例對(duì)象。

示例1

下面示例設(shè)計(jì)一個(gè) Car 類(lèi)型:包含汽車(chē)顏色、驅(qū)動(dòng)輪數(shù)、百公里油耗 3 個(gè)屬性,同時(shí)定義一個(gè)方法,用來(lái)顯示汽車(chē)顏色。

function Car (color, drive, oil) {  //汽車(chē)類(lèi)
    var _car =  new Object();  //臨時(shí)對(duì)象
        _car.color = color;  //初始化顏色
        _car.drive = drive;  //初始化驅(qū)動(dòng)輪數(shù)
        _car.oil = oil;  //初始化百公里油耗
        _car.showColor = function () {  //方法,提示汽車(chē)顏色
            console.log(this.color);
        };
        return _car;  //返回實(shí)例
}
var car1 = Car("red", 4, 8);
var car2 = Car("blue", 2, 6);
car1.showColor();  //輸出“red”
car2.showColor();  //輸出“blue”

上面代碼是一個(gè)簡(jiǎn)單的工廠模式類(lèi)型,使用 Car 類(lèi)可以快速創(chuàng)建多個(gè)汽車(chē)實(shí)例,它們的結(jié)構(gòu)相同,但是屬性不同,可以初始化不同的顏色、驅(qū)動(dòng)輪數(shù)和百公里油耗。

示例2

在類(lèi)型中,方法就是一種行為或操作,它能夠根據(jù)初始化參數(shù)完成特定任務(wù),具有共性。因此,可以考慮把方法置于 Car() 函數(shù)外面,避免每次實(shí)例化時(shí)都要?jiǎng)?chuàng)建一次函數(shù),讓每個(gè)實(shí)例共享同一個(gè)函數(shù)。

function showColor () {  //公共方法,提示汽車(chē)顏色
    console.log(this.color);
};
function Car (color, drive, oil) {  //汽車(chē)類(lèi)
    var _car = new Object();  //臨時(shí)對(duì)象
        _car.color = color;  //初始化顏色
        _car.drive = drive;  //初始化驅(qū)動(dòng)輪數(shù)
        _car.oil = oil;  //初始化百公里油耗
        _car.showColor = showColor;  //引用外部函數(shù)
    return _car;  //返回實(shí)例
}

在上面這段重寫(xiě)的代碼中,在函數(shù) Car() 之前定義了函數(shù) showColor()。在 Car() 內(nèi)部,通過(guò)引用外部 showColor() 函數(shù),避免了每次實(shí)例化時(shí)都要?jiǎng)?chuàng)建一個(gè)新的函數(shù)。從功能上講,這樣解決了重復(fù)創(chuàng)建函數(shù)的問(wèn)題;但是從語(yǔ)義上講,該函數(shù)不太像是對(duì)象的方法。

類(lèi)繼承

類(lèi)繼承的設(shè)計(jì)方法:在子類(lèi)中調(diào)用父類(lèi)構(gòu)造函數(shù)。

在 JavaScript 中實(shí)現(xiàn)類(lèi)繼承,需要注意以下 3 個(gè)技術(shù)問(wèn)題。

在子類(lèi)中,使用 apply 調(diào)用父類(lèi),把子類(lèi)構(gòu)造函數(shù)的參數(shù)傳遞給父類(lèi)父類(lèi)構(gòu)造函數(shù)。讓子類(lèi)繼承父類(lèi)的私有屬性,即 Parent.apply(this, arguments); 代碼行。

在父類(lèi)和子類(lèi)之間建立原型鏈,即 Sub.prototype = new Parent(); 代碼行。通過(guò)這種方式保證父類(lèi)和子類(lèi)是原型鏈上的上下級(jí)關(guān)系,即子類(lèi)的 prototype 指向父類(lèi)的一個(gè)實(shí)例。

恢復(fù)子類(lèi)的原型對(duì)象的構(gòu)造函數(shù),即 Sub.prototype.constructor=Sub;語(yǔ)句行。當(dāng)改動(dòng) prototype 原型時(shí),就會(huì)破壞原來(lái)的 constructor 指針,所以必須重置 constructor。

示例1

下面示例演示了一個(gè)三重繼承的案例,包括基類(lèi)、父類(lèi)和子類(lèi),它們逐級(jí)繼承。

//基類(lèi)Base
function Base (x) {  //構(gòu)造函數(shù)Base
    this.get = function () {  //私有方法,獲取參數(shù)值
        return x;
    }
}
Base.prototype.has = function () {  //原型方法,判斷get()方法返回值是否為0
    return ! (this.get() == 0);
}
//父類(lèi)Parent
function Parent () {  //構(gòu)造函數(shù)Parent
    var a = [];  //私有數(shù)組a
    a = Array.apply(a, arguments);  //把參數(shù)轉(zhuǎn)換為數(shù)組
    Base.call(this, a.length);  //調(diào)用Base類(lèi),并把參數(shù)數(shù)組長(zhǎng)度傳遞給它
    this.add = function () {  //私有方法,把參數(shù)數(shù)組補(bǔ)加到數(shù)組a中并返回
        return a.push.apply(a, arguments)
    }
    this.geta = function () {  //私有方法,返回?cái)?shù)組a
        return a;
    }
}
Parent.prototype = new Base();  //設(shè)置Parent原型為Base的實(shí)例,建立原型鏈
Parent.prototype.constructor = Parent;  //恢復(fù)Parent類(lèi)原型對(duì)象的構(gòu)造器
Parent.prototype.str = function (){  //原型方法,把數(shù)組轉(zhuǎn)換為字符串并返回
    return this.geta().toString();
}
//子類(lèi)Sub
function Sub () {  //構(gòu)造函數(shù)
    Parent.apply(this, arguments);  //調(diào)用Parent類(lèi),并把參數(shù)數(shù)組長(zhǎng)度傳遞給它
    this.sort = function () {  //私有方法,以字符順序?qū)?shù)組進(jìn)行排序
        var a = this.geta();  //獲取數(shù)組的值
        a.sort.apply(a, arguments);  //調(diào)用數(shù)組排序方法 sort()對(duì)數(shù)組進(jìn)行排序
    }
}
Sub.prototype = new Parent();  //設(shè)置Sub原型為Parent實(shí)例,建立原型鏈
Sub.prototype.constructor = Sub;  //恢復(fù)Sub類(lèi)原型對(duì)象的構(gòu)造器
//父類(lèi)Parent的實(shí)例繼承類(lèi)Base的成員
var parent = new Parent (1, 2, 3, 4);  //實(shí)例化Parent類(lèi)
console.log(parent.get());  //返回4,調(diào)用Base類(lèi)的方法get()
console.log(parent.has());  //返回true,調(diào)用Base類(lèi)的方法has()
//子類(lèi)Sub的實(shí)例繼承類(lèi)Parent和類(lèi)Base的成員
var sub = new Sub (30, 10, 20, 40);  //實(shí)例化Sub類(lèi)
sub.add(6, 5);  //調(diào)用Parent類(lèi)方法add(),補(bǔ)加數(shù)組
console.log(sub.geta());  //返回?cái)?shù)組30,10,20,40,6,5
sub.sort();  //排序數(shù)組
console.log(sub.geta());  //返回?cái)?shù)組10,20,30,40,5,6
console.log(sub.get());  //返回4,調(diào)用Base類(lèi)的方法get()
console.log(sub.has());  //返回true,調(diào)用Base類(lèi)的方法has()
console.log(sub.str());  //返回10,20,30,40,5,6

【設(shè)計(jì)思路】

設(shè)計(jì)子類(lèi) Sub 繼承父類(lèi) Parent,而父類(lèi) Parent 又繼承基類(lèi) Base。Base、Parent、Sub 三個(gè)類(lèi)之間的繼承關(guān)系是通過(guò)在子類(lèi)中調(diào)用的構(gòu)造函數(shù)來(lái)維護(hù)的。

例如,在 Sub 類(lèi)中,Parent.apply(this, arguments); 能夠在子類(lèi)中調(diào)用父類(lèi),并把子類(lèi)的參數(shù)傳遞給父類(lèi),從而使子類(lèi)擁有父類(lèi)的所有屬性。

同理,在父類(lèi)中,Base.call(this, a.length); 把父類(lèi)的參數(shù)長(zhǎng)度作為值傳遞給基類(lèi),并進(jìn)行調(diào)用,從而實(shí)現(xiàn)父類(lèi)擁有基類(lèi)的所有成員。

從繼承關(guān)系上看,父類(lèi)繼承了基類(lèi)的私有方法 get(),為了確保能夠繼承基類(lèi)的原型方法,還需要為它們建立原型鏈,從而實(shí)現(xiàn)原型對(duì)象的繼承關(guān)系,方法是添加語(yǔ)句行 Parent.prototype=new Base();。

同理,在子類(lèi)中添加語(yǔ)句 Sub.prototype=new Parent();,這樣通過(guò)原型鏈就可以把基類(lèi)、父類(lèi)和子類(lèi)串連在一起,從而實(shí)現(xiàn)子類(lèi)能夠繼承父類(lèi)屬性,還可以繼承基類(lèi)的屬性。

示例2

下面嘗試把類(lèi)繼承模式封裝起來(lái),以便規(guī)范代碼應(yīng)用。

function extend (Sub, Sup) {  //類(lèi)繼承封裝函數(shù)
    var F = function () {};  //定義一個(gè)空函數(shù)
    F.prototype = Sup.prototype;  //設(shè)置空函數(shù)的原型為父類(lèi)的原型
    Sub.prototype = new F ();  //實(shí)例化空函數(shù),并把父類(lèi)原型引用傳給給子類(lèi)
    Sub.prototype.constructor = Sub;  //恢復(fù)子類(lèi)原型的構(gòu)造器為子類(lèi)自身
    Sub.sup = Sup.prototype;  //在子類(lèi)定義一個(gè)私有屬性存儲(chǔ)父類(lèi)原型
    //檢測(cè)父類(lèi)原型構(gòu)造器是否為自身
    if (Sup.prototype.constructor == Object.prototype.constructor) {
        Sup.prototype.constructor = Sup;  //類(lèi)繼承封裝函數(shù)
    }
}

【操作步驟】

1) 定義一個(gè)封裝函數(shù)。設(shè)計(jì)入口為子類(lèi)和父類(lèi)對(duì)象,函數(shù)功能是子類(lèi)能夠繼承父類(lèi)的所有原型成員,不涉及出口。

function extend (Sub, Sup) {  //類(lèi)繼承封裝函數(shù)
    //其中參數(shù)Sub表示子類(lèi),Sup表示父類(lèi)
}

2) 在函數(shù)體內(nèi),首先定義一個(gè)空函數(shù) F,用來(lái)實(shí)現(xiàn)功能中轉(zhuǎn)。設(shè)計(jì)它的原型為父類(lèi)的原型,然后把空函數(shù)的實(shí)例傳遞給子類(lèi)的原型,這樣就避免了直接實(shí)例化父類(lèi)可能帶來(lái)的系統(tǒng)負(fù)荷。因?yàn)樵趯?shí)際開(kāi)發(fā)中,父類(lèi)的規(guī)??赡軙?huì)很大,如果實(shí)例化,會(huì)占用大量?jī)?nèi)存。

3) 恢復(fù)子類(lèi)原型的構(gòu)造器為子類(lèi)自己。同時(shí),檢測(cè)父類(lèi)原型構(gòu)造器是否與 Object 的原型構(gòu)造器發(fā)生耦合。如果是,則恢復(fù)它的構(gòu)造器為父類(lèi)自身。

下面定義兩個(gè)類(lèi),嘗試把它們綁定為繼承關(guān)系。

function A (x) {  //構(gòu)造函數(shù)A
    this.x = x;  //私有屬性x
    this.get = function () {  //私有方法get()
        return this.x;
    }
}
A.prototype.add = function () {  //原型方法add()
    return this.x + this.x;
}
A.prototype.mul = function () {  //原型方法mul()
    return this.x * this.x;
}
function B (x) {  //構(gòu)造函數(shù)B
    A.call (this.x);  //在函數(shù)體內(nèi)調(diào)用構(gòu)造函數(shù)A,實(shí)現(xiàn)內(nèi)部數(shù)據(jù)綁定
}
extend (B, A);  //調(diào)用封裝函數(shù),把A和B的原型捆綁在一起
var f = new B (5);  //實(shí)例化類(lèi)B
console.log(f.get());  //繼承類(lèi)A的方法get(),返回5
console.log(f.add());  //繼承類(lèi)A的方法add(),返回10
console.log(f.mul());  //繼承類(lèi)A的方法mul(),返回25

在函數(shù)類(lèi)封裝函數(shù)中,有這么一句 Sub.sup=Sup.prototype;,在上面代碼中沒(méi)有被利用,那么它有什么作用呢?為了解答這個(gè)問(wèn)題,先看下面的代碼。

extend (B, A);
B.prototype.add = function () {  //為B類(lèi)定義一個(gè)原型方法
    return this.x + "" + this.x;
}

上面的代碼是在調(diào)用封裝函數(shù)之后,再為 B 類(lèi)定義了一個(gè)原型方法,該方法名與基類(lèi)中原型方法 add() 同名,但是功能不同。如果此時(shí)測(cè)試程序,會(huì)發(fā)現(xiàn)子類(lèi) B 定義的原型方法 add() 將會(huì)覆蓋父類(lèi) A 的原型方法 add()。

console.log(f.add());  //返回字符串55,而不是數(shù)值10

如果在 B 類(lèi)的原型方法 add() 中調(diào)用父類(lèi)的原型方法 add(),避免代碼耦合現(xiàn)象發(fā)生。

B.prototype.add = function () {  //定義子類(lèi)B的原型方法add()
    return B.sup.add.call(this);  //在函數(shù)內(nèi)部調(diào)用父類(lèi)方法add()
}

以上就是“javascript繼承的作用是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網(wǎng)站欄目:javascript繼承的作用是什么
網(wǎng)址分享:http://weahome.cn/article/gopesg.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部