成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【10】JavaScript 面向?qū)ο蟾呒墶^承模式

0xE7A38A / 1307人閱讀

摘要:面向?qū)ο蟾呒壚^承模式一原型鏈繼承方式原型鏈繼承流程定義父類型構(gòu)造函數(shù)。缺點(diǎn)無法避免構(gòu)造函數(shù)模式存在的問題方法都在構(gòu)造函數(shù)中定義,無法函數(shù)復(fù)用。六寄生組合式繼承在這里重復(fù)一下組合繼承的代碼組合繼承最大的缺點(diǎn)是會調(diào)用兩次父構(gòu)造函數(shù)。

JavaScript 面向?qū)ο蟾呒墶^承模式 一、原型鏈繼承

方式1: 原型鏈繼承

(1)流程:

? 1、定義父類型構(gòu)造函數(shù)。

? 2、給父類型的原型添加方法。

? 3、定義子類型的構(gòu)造函數(shù)。

? 4、創(chuàng)建父類型的對象賦值給子類型的原型。

? 5、將子類型原型的構(gòu)造屬性設(shè)置為子類型。

? 6、給子類型原型添加方法。

? 7、創(chuàng)建子類型的對象: 可以調(diào)用父類型的方法。

(2)關(guān)鍵:

子類型的原型為父類型的一個實(shí)例對象

// 1.定義父類型構(gòu)造函數(shù)
function Supper() {
  this.supProp = "Supper property"
}
// 2.給父類型的原型添加方法
Supper.prototype.showSupperProp = function () {
  console.log(this.supProp)
}
// 3.定義子類型的構(gòu)造函數(shù)
function Sub() {
  this.subProp = "Sub property"
}
// 4.子類型的原型為父類型的一個實(shí)例對象
Sub.prototype = new Supper()
// 5.將子類型原型的構(gòu)造屬性constructor指向子類型
Sub.prototype.constructor = Sub
// 6.給子類型原型添加方法
Sub.prototype.showSubProp = function () {
  console.log(this.subProp)
}
// 7.創(chuàng)建子類型的對象,可以調(diào)用父類型的方法
var sub = new Sub()
sub.showSupperProp()  // Supper property
sub.showSubProp()  // Sub property
console.log(sub)  // Sub

(3)缺點(diǎn):

1、包含引用類型值的原型,由于實(shí)例共享屬性,一個實(shí)例對原型屬性的修改會在另一個實(shí)例中反映出來。

2、不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。

二、借用構(gòu)造函數(shù)繼承

方式2: 借用構(gòu)造函數(shù)繼承。

(1)流程:

? 1、定義父類型構(gòu)造函數(shù)。

? 2、定義子類型構(gòu)造函數(shù)。

? 3、在子類型構(gòu)造函數(shù)中調(diào)用父類型構(gòu)造。

// 1.定義父類型構(gòu)造函數(shù)
function Person(name, age) {
  this.name = name
  this.age = age
}
// 2.定義子類型構(gòu)造函數(shù)
function Student(name, age, price) {
  // 3.在子類型構(gòu)造函數(shù)中調(diào)用父類型構(gòu)造
  Person.call(this, name, age)  // 相當(dāng)于: this.Person(name, age)
  /*this.name = name
  this.age = age*/
  this.price = price
}

var s = new Student("Tom", 20, 14000)
console.log(s.name, s.age, s.price) // Tom 20 14000

(2)關(guān)鍵:

在子類型構(gòu)造函數(shù)中通過call()調(diào)用父類型構(gòu)造函數(shù)。

(3)缺點(diǎn):

1、無法避免構(gòu)造函數(shù)模式存在的問題——方法都在構(gòu)造函數(shù)中定義,無法函數(shù)復(fù)用。

2、在父類型原型中定義的方法在子類型中是不可見的,只能繼承父類型構(gòu)造函數(shù)中定義的屬性和方法。

三、組合繼承

方式3: 原型鏈+借用構(gòu)造函數(shù)的組合繼承。

1、利用原型鏈實(shí)現(xiàn)對父類型對象的方法繼承。

2、利用call()借用父類型構(gòu)造函數(shù)初始化相同屬性。

function Person(name, age) {
  this.name = name
  this.age = age
}

Person.prototype.setName = function (name) {
  this.name = name
}

function Student(name, age, price) {
  Person.call(this, name, age)  // 為了得到屬性
  this.price = price
}

Student.prototype = new Person() // 為了能看到父類型的方法
Student.prototype.constructor = Student //修正constructor屬性
Student.prototype.setPrice = function (price) {
  this.price = price
}

var s = new Student("Tom", 24, 15000)
s.setName("Bob")
s.setPrice(16000)
console.log(s.name, s.age, s.price)
四、原型式繼承
function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

就是 ES5 Object.create 的模擬實(shí)現(xiàn),將傳入的對象作為創(chuàng)建的對象的原型。

缺點(diǎn):包含引用類型的屬性值始終都會共享相應(yīng)的值,這點(diǎn)跟原型鏈繼承一樣。

var person = {
    name: "kevin",
    friends: ["daisy", "kelly"]
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = "person1";
console.log(person2.name); // kevin
person1.firends.push("taylor");
console.log(person2.friends); // ["daisy", "kelly", "taylor"]

注意:修改person1.name的值,person2.name的值并未發(fā)生改變,并不是因?yàn)?b>person1和person2有獨(dú)立的 name 值,而是因?yàn)?b>person1.name = "person1",給person1添加了 name 值,并非修改了原型上的 name 值。

五、寄生式繼承

創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種形式來做增強(qiáng)對象,最后返回對象。

function createObj (o) {
    var clone = Object.create(o);
    clone.sayName = function () {
        console.log("hi");
    }
    return clone;
}

缺點(diǎn):跟借用構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對象都會創(chuàng)建一遍方法。

六、寄生組合式繼承

在這里重復(fù)一下組合繼承的代碼:

function Parent (name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

Child.prototype = new Parent();

var child1 = new Child("kevin", "18");

console.log(child1)

組合繼承最大的缺點(diǎn)是會調(diào)用兩次父構(gòu)造函數(shù)。

一次是設(shè)置子類型實(shí)例的原型的時候:

Child.prototype = new Parent();

一次在創(chuàng)建子類型實(shí)例的時候:

var child1 = new Child("kevin", "18");

回想下 new 的模擬實(shí)現(xiàn),其實(shí)在這句中,我們會執(zhí)行:

Parent.call(this, name);

在這里,我們又會調(diào)用了一次 Parent 構(gòu)造函數(shù)。

所以,在這個例子中,如果我們打印 child1 對象,我們會發(fā)現(xiàn) Child.prototypechild1 都有一個屬性為colors,屬性值為["red", "blue", "green"]。

那么我們該如何精益求精,避免這一次重復(fù)調(diào)用呢?

如果我們不使用 Child.prototype = new Parent() ,而是間接的讓 Child.prototype 訪問到 Parent.prototype 呢?

看看如何實(shí)現(xiàn):

function Parent (name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

// 關(guān)鍵的三步
var F = function () {};

F.prototype = Parent.prototype;

Child.prototype = new F();


var child1 = new Child("kevin", "18");

console.log(child1);

最后我們封裝一下這個繼承方法:

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

function prototype(child, parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}

// 當(dāng)我們使用的時候:
prototype(Child, Parent);

引用《JavaScript高級程序設(shè)計(jì)》中對寄生組合式繼承的夸贊就是:

這種方式的高效率體現(xiàn)它只調(diào)用了一次 Parent 構(gòu)造函數(shù),并且因此避免了在 Parent.prototype 上面創(chuàng)建不必要的、多余的屬性。與此同時,原型鏈還能保持不變;因此,還能夠正常使用 instanceofisPrototypeOf。開發(fā)人員普遍認(rèn)為寄生組合式繼承是引用類型最理想的繼承范式。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105094.html

相關(guān)文章

  • JavaScript構(gòu)造器理解

    摘要:類類的概念應(yīng)該是面向?qū)ο笳Z言的一個特色,但是并不像,等高級語言那樣擁有正式的類,而是多數(shù)通過構(gòu)造器以及原型方式來仿造實(shí)現(xiàn)。因此,出現(xiàn)了構(gòu)造函數(shù)方式,它的關(guān)鍵在于構(gòu)造器概念的引入。于是,這就產(chǎn)生了構(gòu)造函數(shù)原型法的類構(gòu)造方法。 類 Class 類的概念應(yīng)該是面向?qū)ο笳Z言的一個特色,但是JavaScript并不像Java,C++等高級語言那樣擁有正式的類,而是多數(shù)通過構(gòu)造器以及原型方式...

    PiscesYE 評論0 收藏0
  • JS面向對象的程序設(shè)計(jì)之繼承的實(shí)現(xiàn)-組合繼承

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

    antz 評論0 收藏0
  • JavaScript面向對象程序設(shè)計(jì)

    摘要:構(gòu)造函數(shù)模式這種方法創(chuàng)建自定義的構(gòu)造函數(shù),從而自定義對象類型的屬性和方法。借用構(gòu)造函數(shù)在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù),通過和方法來實(shí)現(xiàn)。 JavaScript中沒有類的概念,它不是嚴(yán)格意義上的面向?qū)ο笳Z言,而是基于對象(Object-based)的編程語言。下面是讀《JavaScript高級程序設(shè)計(jì)(第三版)》的學(xué)習(xí)筆記,總結(jié)一些常用的創(chuàng)建對象和繼承的方法。 一、創(chuàng)建對象 1...

    wfc_666 評論0 收藏0
  • 我來重新學(xué)習(xí)js 的面向對象(part 5)

    摘要:無限增殖返回蘋果返回香蕉返回返回使用的新語法方法會創(chuàng)建一個新對象,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的。是新增的,用來規(guī)范原型式繼承。這里將返回的新對象放到子類的原型對象里面,這樣子類就擁有了父類的原型對象,也就實(shí)現(xiàn)了方法的繼承。 這是最后的最后了,我會順便總結(jié)一下各種繼承方式的學(xué)習(xí)和理解。(老板要求什么的,管他呢) 一、繼承-組合繼承、偽經(jīng)典繼承 showImg(https://seg...

    BicycleWarrior 評論0 收藏0
  • 2017年 最好的javascript 書籍

    摘要:請記住,這些書中的一些可能不是最新的,但概念和基礎(chǔ)仍應(yīng)適用。是最好的老師之一。的秘密由部分組成。在你完成這些書后,查看書籍和最好的本土?xí)? 我看過三本,第1本,第二本,第四本。第一本買的的實(shí)體書,其他兩本看的是電子書。第一本是大名鼎鼎老道寫的,書很薄,但是非常經(jīng)典。javascirpt忍者秘籍是jquery的作者寫的,也是非常經(jīng)典。you dont kown js系列也是非常好??戳?..

    mingzhong 評論0 收藏0

發(fā)表評論

0條評論

0xE7A38A

|高級講師

TA的文章

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