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

資訊專欄INFORMATION COLUMN

JS繼承

Tangpj / 1766人閱讀

摘要:繼承創建子類型的實例時,不能向超類型的構造函數中傳遞參數。借用構造函數偽造對象經典繼承在子類型構造函數內部調用超類型構造函數。組合繼承使用原型鏈實現對原型屬性和方法的繼承,而通過構造函數來實現實例屬性的繼承。

JS繼承 原型鏈 構造函數、原型、實例的關系

每個構造函數都有一個原型對象,原型對象包含一個指向構造函數的指針,而實例包含一個指向構造函數的指針。
原型鏈的構建是通過將一個類型的實例賦值給另一個構造函數的原型實現。

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

SubType繼承SuperType是通過創建SuperType實例,并將該實例賦給SubType.prototype實現的。本質是重寫原型對象,代之以一個新類型的實例。
instance指向SubType的原型,SubType的原型又指向SuperType的原型。要注意的是instance.constructor現在指向的是SuperType,應為SubType的原型指向了SuperType的原型,而該原型對象的constructor屬性指向的SuperType。

原型搜索機制

調用instance.getSuperValue()會經歷一下三個步驟:
1)搜索實例
2)搜索SubType.prototype
3)搜索SuperType.prototype,最后一步才會找到該方法。在找不到屬性或方法的情況下,搜索過程總要一環一環地前行到原型鏈末端為止。

確定原型與實例的關系

1.instanceof
instance instanceof Object
2.isPrototypeOf
Object.prototype.isPrototypeOf(instance)

定義方法

1.子類型需要覆蓋超類型中的某個方法,或需要添加超類型中不存在的某個方法。給原型添加方法的代碼要放在替換原型的語句后面。

    function SuperType(){
        this.property=true;
    }
    SuperType.prototype.getSuperValue=function () {
        return this.property;
    };
    function SubType(){
        this.subproperty=false;
    }
    //繼承SuperType
    SubType.prototype=new SuperType();
    //添加新方法
    SuperType.prototype.getSubValue=function () {
        return this.subproperty;
    }
    //重寫超類型中的方法
    SubType.prototype.getSuperValue=function () {
        return false;
    }
    var instance=new SubType();
    console.log(instance.getSuperValue());

2.通過原型鏈實現繼承時,不能使用對象字面量創建原型方法。這樣會重寫原型鏈。

    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;
        }
    };
    var instance=new SubType();
    console.log(instance.getSuperValue());  //error

以上代碼先把SuperType的實例賦值給原型,緊接著又將原型替換成一個對象字面量。由于現在的原型包含的是一個Object實例,而非SuperType的實例。因此,原來的SuperType和SubType之間的原型鏈被切斷。

原型鏈的問題

1.包含引用類型的原型屬性會被所有實例共享。

    function SuperType(){
        this.nums=[1,2];
    }
    function SubType(){

    }
    //繼承SuperType
    SubType.prototype=new SuperType();
    var instance=new SubType();
    instance.nums.push(5);
    console.log(instance.nums);  //[1,2,5]
    var instance1=new SubType();
    instance1.nums.push(0);
    console.log(instance1.nums);  //[1,2,5,0]

2.創建子類型的實例時,不能向超類型的構造函數中傳遞參數。

借用構造函數(偽造對象/經典繼承)

在子類型構造函數內部調用超類型構造函數。

function SuperType(){
    this.nums=[1,2];
}
function SubType() {
    SuperType.call(this);
}
SubType.prototype=new SubType();
var instance=new SubType();
instance.nums.push(3);
console.log(instance.nums);

var instance2=new SubType();
console.log(instance2.nums);

通過使用call()方法(或apply()方法),在新創建的SubType實例的環境下調用了SuperType構造函數。這樣就會在新SubType對象上執行SuperType函數中定義的所有對象初始化代碼。SubType的每個實例都會具有自己的nums屬性的副本。
1.傳遞參數
子類型構造函數向超類型構造函數傳遞參數。

function SuperType(name){
    this.name=name;
    this.school=["whu"];
}
function SubType() {
    SuperType.call(this,"張三");
    //實例屬性
    this.age=20;
}
var instance=new SubType();
instance.school.push("hhu");
console.log(instance.name);
console.log(instance.age);
console.log(instance.school);
var instance2=new SubType();
console.log(instance2.school);

2.存在的問題
方法都在構造函數中定義,函數無法復用;
在超類型的原型中定義的方法,對于子類型而言是不可見的,那么所有類型都只能使用構造函數模式。

組合繼承

使用原型鏈實現對原型屬性和方法的繼承,而通過構造函數來實現實例屬性的繼承。

function SuperType(name){
    this.name=name;
    this.city=["武漢","杭州"];
}
SuperType.prototype.sayName=function () {
    console.log(this.name);
}
function SubType(name,age) {
    //繼承屬性
    SuperType.call(this,name);
    //實例屬性
    this.age=age;
}
//繼承方法
    SubType.prototype=new SuperType();
SubType.prototype.constructor=SubType;
SubType.prototype.sayAge=function () {
    console.log(this.age);
}

var instance1=new SubType("chen",18);
instance1.city.push("北京");
console.log(instance1.city);
instance1.sayName();
instance1.sayAge();
var instance2=new SubType("huang",19);
console.log(instance2.city);
instance2.sayName();
instance2.sayAge();
原型式繼承
function object(o){
    function F(){}
    F.prototype=o;
    return new F();
}

在object函數內部,先創建一個臨時性的構造函數,然后將傳入對象作為這個構造函數的原型,最后返回了這個臨時類型的一個新實例。本質上是object()對傳入其中的對象執行了一次淺復制。

var navy={
    name:"海軍",
    weapon:["航母","驅逐艦"]
};
function object(o){
    function F() {

    }
    F.prototype=o;
    return new F();
}
var navy1=object(navy);
navy1.name="俄羅斯";
navy1.weapon.push("巡洋艦");
var navy2=object(navy);
navy2.name="美國";
navy2.weapon.push("護衛艦");
console.log(navy.weapon);

ECMAScript5新增Object.create()方法規范了原型式繼承,接收兩個參數:一個是作用于新對象原型的對象,(可選)二是一個新對象定義額外屬性的對象.

var car={
    name:"奔馳",
    weapon:["車輪","發動機"]
};
var car1=Object.create(car,{
    name:{
        value:"寶馬"
    }
});
console.log(car1.name);

原型式的問題依然是包含引用類型的屬性會所有實例被共享

寄生式繼承
    function object(o){
        function F() {

        }
        F.prototype=o;
        return new F();
    }
    function createAnother(original) {
        var clone=object(original);  //通過調用函數創建一個新對象
        clone.sayHi=function () {   //以某種方式增強這個對象
            console.log("hi");
        };
        return clone;   //返回對象
    }
    var person={
        name:"coder",
        ability:["Java","R"]
    };
    var another=createAnother(person);
    another.sayHi();

寄生式的問題依然是不能做到函數復用

寄生組合式繼承

組合繼承最大的問題就是會調用兩次超類型構造函數:一次是創建子類型原型時候,一次是在子類型構造函數內部。

    function SuperType(name){
        this.name=name;
        this.city=["南京","蘇州"];
    }
    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.constructor=SubType;
    SubType.prototype.sayAge=function () {
        console.log(this.age);
    }

在第一次調用SuperType構造函數時,SubType.prototype會得到兩個屬性:name和colors;都是SuperType的實例屬性,只不過現在位于SubType的原型中.當調用SubType構造函數,又會調用一次SuperType的構造函數,這一次又在新對象上創建了實例屬性name和colors.于是這兩個屬性就屏蔽了原型中的兩個同名屬性.
寄生組合式繼承通過借用構造函數來繼承屬性,通過原型鏈的混成形式來繼承方法.其基本思想是:不必為了指定子類型的原型而調用超類型的構造函數,所需要的只是超類型原型的一個副本.本質上,就是使用寄生式繼承來繼承超類型的原型,然后再講結果指定給子類型的原型.

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

inheritPrototype函數接受兩個參數:子類型構造函數、超類型構造函數
1.創建超類型原型的一個副本
2.為創建的副本添加constructor屬性,彌補因重寫原型而失去的默認的constructor屬性.
3.將新創建的對象(即副本)賦值給子類型的原型.

    function SuperType(name){
        this.name=name;
        this.city=["南京","蘇州"];
    }
    SuperType.prototype.sayName=function () {
        console.log(this.name);
    }
    function SubType(name,age) {
        SuperType.call(this,name);//第二次調用SuperType
        this.age=age;
    }
    inheritPrototype(SubType,SubType);
    SubType.prototype.sayAge=function () {
        console.log(this.age);
    }

上述只調用了一次SuperType構造函數,并因此避免了在SubType.ptototype上創建不必要的、多余的屬性.與此同時,原型鏈還能保持不變.

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93627.html

相關文章

  • JS中的繼承(上)

    摘要:中的繼承上學過或者之類語言的同學應該會對的繼承感到很困惑不要問我怎么知道的的繼承主要是基于原型的對的原型感興趣的同學可以了解一下我之前寫的中的原型對象相信很多同學也跟我一樣剛開始接觸的面向對象編程的時候都抱著一種排斥的心態為什么這么 JS中的繼承(上) 學過java或者c#之類語言的同學,應該會對js的繼承感到很困惑--不要問我怎么知道的,js的繼承主要是基于原型(prototype)...

    Fundebug 評論0 收藏0
  • JavaScript繼承方式詳解

    摘要:可以通過構造函數和原型的方式模擬實現類的功能。原型式繼承與類式繼承類式繼承是在子類型構造函數的內部調用超類型的構造函數。寄生式繼承這種繼承方式是把原型式工廠模式結合起來,目的是為了封裝創建的過程。 js繼承的概念 js里常用的如下兩種繼承方式: 原型鏈繼承(對象間的繼承) 類式繼承(構造函數間的繼承) 由于js不像java那樣是真正面向對象的語言,js是基于對象的,它沒有類的概念。...

    Yangyang 評論0 收藏0
  • JS面向對象之五 【繼承

    摘要:首先為了模擬類創建對象的功能搞出了構造函數。也就是名字膚色膚色這里是繼承里的自有屬性生命值這里繼承的共有屬性的方法攻擊力兵種美國大兵攻擊防御死亡膚色 JS面向對象之五 【繼承】 我們已經準備了很多前置知識,包括 原型鏈,對象和對象之間的關系 this,對象和函數之間的關系 new, 用函數批量創建特定的對象的語法糖 JS面向對象的前世今生 我們說,面向對象是一種寫代碼的套路。因為如...

    genefy 評論0 收藏0
  • JS基礎(對象創建,構造函數、原型、實例之間關系,繼承方式)

    摘要:對象創建的三種方式字面量創建方式系統內置構造函數方式自定義構造函數構造函數原型實例之間的關系實例是由構造函數實例化創建的,每個函數在被創建的時候,都會默認有一個對象。 JS 對象創建的三種方式 //字面量創建方式 var person= { name:jack?。? //系統內置構造函數方式 var person= new Object(); person.name = jack; ...

    PAMPANG 評論0 收藏0
  • JS專題之繼承

    摘要:構造函數所以,就有了畸形的繼承方式原型鏈繼承三原型鏈繼承改變構造函數的原型對象繼承了屬性以上例子中,暴露出原型鏈繼承的兩個問題包含引用類型數據的原型屬性,會被所有實例共享,基本數據類型則不會。 前言 眾所周知,JavaScript 中,沒有 JAVA 等主流語言類的概念,更沒有父子類繼承的概念,而是通過原型對象和原型鏈的方式實現繼承。 于是,我們這一篇講一講 JS 中的繼承(委托)。 ...

    rollback 評論0 收藏0
  • js原型和繼承

    摘要:舉例說明組合繼承組合繼承利用原型鏈借用構造函數的模式解決了原型鏈繼承和類式繼承的問題。示例組合式繼承是比較常用的一種繼承方法,其背后的思路是使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承。 對js原型和繼承的理解一直處于不懂-懂-不懂-懂-不懂。。。的無限循環之中,本來打算只是簡單總結下js繼承方式,可看了些網上的資料后,發現又不懂繼承了。。。這篇文章只...

    Hujiawei 評論0 收藏0

發表評論

0條評論

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