關於js繼承實現



1.原型鏈實現。原型鏈這東西有點像作用域鏈。
    function SuperType() {
        this.property = true;
    }
    SuperType.prototype.getSuperType = function () {
        return this.property;
    };




    function SubType() {
        this.subProperty = false;
        this.property = false;
    }
    SubType.prototype = new SuperType();
    SubType.prototype.getSubType = function () {
        return this.subProperty;
    };


    var subType = new SubType();//這步重點;要添加其他的方法要在這一步之後進行
    alert(subType.subProperty);
    alert(subType.getSubType());
    alert(subType.property);
    alert(subType.getSuperType());
原型鏈實現的時候,搜索一個方法或者屬性的步驟與作用域鏈類似。先搜索實例本身,然後搜索實例所屬的構造函數的prototype,最後搜索父類的原型。
使用原型進行繼承,引用值類型的屬性、方法都是共享的,當然也會被子類繼承。而且,使用原型是無法向父類進行傳參的。
實踐中用的少!!
2.借用構造函數。這種思想,簡而言之就是在子類的構造函數中調用父類的構造函數,使用call()或者apply().
call和apply方法其實就是動態修改this所指的對象。區別在於call的參數是固定的,被調用的對象.方法.call(需要調用的對象,參數1,參數2,...)。applay的參數是不固定的被調用的對象.方法.call(需要調用的對象,argument[])
    function SuperType() {
        this.property = true;
        this. getSupType=function() {
            return this.property;
        }    
    }
    SuperType.prototype.getSuperType = function () {
        return this.property;
    };




    function SubType() {
        this.subProperty = false;
        this.property = false;
        SuperType.call(this);
    }


    var subType = new SubType();
    alert(subType.subProperty);//false
    //alert(subType.getSubType());
    alert(subType.property);//true,這裡之所以是true,因為this.property = false;在SuperType.call(this);之前,調用後一句的時候會覆蓋上一句,如果調換順序親測則會顯示false
    //alert(subType.getSuperType());
    //在超類原型中定義的方法是識別不到的,能識別到的只有在構造函數中定義的方法。
    //在父类构造函数中定义如此的方法也是无法识别到的
    //function getSupType() {
    //return this.property;
    //}
    alert(subType.getSupType());//true
此種繼承方法,方法都在構造函數中定義,函數無法複用。原型中的方法與屬性無法識別,一切都只能在構造函數中進行。實踐中少用。
3.組合繼承。它的思想就是組合了構造函數繼承與原型繼承。使用原型鏈實現對原型屬性和方法的繼承,通過構造函數實現對實例屬性的繼承。
    function SuperType() {
        this.propertyInConstructor = 'super propertyInConstructor';
        this.sayHiInConstructor = function () {
            return 'hi, super constructor';
        };
    }
    SuperType.prototype.propertyInPrototype = 'super propertyInPrototype';
    SuperType.prototype.sayHiInPrototype = function () {
        return 'hi, supper prototype';
    };


    function SubType() {
        this.subPropertyInConstructor = 'sub propertyInConstructor';
        SuperType.call(this);//继承属性,第二次調用父類的構造函數,會覆蓋之前創建的實例屬性以及原型中的同名屬性(原型中的同名屬性是由於繼承得來的)
    }
    SubType.prototype = new SuperType();//第一次調用父類的構造函數
    SubType.prototype.showProperty = function () {
        return this.subPropertyInConstructor;
    }


    var sub = new SubType();
    alert(sub.subPropertyInConstructor);//sub propertyInConstructor
    alert(sub.showProperty());//sub propertyInConstructor
    alert(sub.propertyInConstructor);//super propertyInConstructor
    alert(sub.sayHiInConstructor())//hi, super constructor,如果不加括号,直接已字符串方式显示方法
    alert(sub.propertyInPrototype);//super propertyInPrototype
    alert(sub.sayHiInPrototype());//hi, supper prototype
最常用的集成模式。兩次調用父類的構造函數。
4.原型繼承。大概思想是利用已有的原型創建方法創建對象,然後返回該對象。
    function object(o) {
        function Fun() { };//先创建一个临时的构造函数
        Fun.prototype = o;//然后将传入的对象作为这个构造函数的原型
        return new Fun();//最后返回这个临时构造函数的实例
    }


    var person = {
        name: 'chan',
        colors:['red']
    };
    var anotherPerson = object(person);//其实就是对person的一次浅复制
    anotherPerson.name = 'ky';
    anotherPerson.colors.push('yellow');


    var yetAnotherPerson = object(person);
    yetAnotherPerson.name = 'gy';
    yetAnotherPerson.colors.push('black');


    alert(anotherPerson.name + ' ' + anotherPerson.colors.join('|'));//ky red|yellow|black
    alert(yetAnotherPerson.name + ' ' + yetAnotherPerson.colors.join('|'));//gy red|yellow|black
這實際上就是創建了兩個person的副本,對於引用型的屬性是共享的。
5.寄生式繼承。大概思路是創建一個用於封裝繼承過程的函數,最終結果是返回一個對象。
    function object(o) {
        function Fun() { };//先创建一个临时的构造函数
        Fun.prototype = o;//然后将传入的对象作为这个构造函数的原型
        return new Fun();//最后返回这个临时构造函数的实例
    }


    function createAnother(original) {
        var clone = object(original);
        clone.sayHi = function () {
            return 'hi';
        };
        return clone;
    }


    var person = {
        name: 'chan',
        colors: ['red']
    };


    var anotherPerson = createAnother(person);
    alert(anotherPerson.sayHi());//hi
該方法無法做到方法的複用。如果是不考慮對象的屬性與方法,僅僅為了產生一個對象的話,該方法是不錯的選擇。
6.寄生組合式繼承。通過借用構造函數來繼承屬性,通過原型鏈的混成形式來繼承方法。其實就是在指定子類型的原型的時候不調用超類型的構造函數,而是使用寄生式繼承來實現超類型的一個副本并將結果指定給子類型的原型。
    function object(o) {
        function Fun() { };//先创建一个临时的构造函数
        Fun.prototype = o;//然后将传入的对象作为这个构造函数的原型
        return new Fun();//最后返回这个临时构造函数的实例
    }
    //这里只是复制,没有调用
    function inheritPrototype(subType, superType) {
        var prototype = object(superType.prototype);
        prototype.constructor = subType;
        subType.prototype = prototype;
    }


    function SuperType() {
        this.name = 'chan';
        this.colors = ['red'];
    }
    SuperType.prototype.sayHi = function () {
        return 'hi ' + this.name+' '+this.colors.join('|');
    }


    function SubType() {
        SuperType.call(this);
    }
    inheritPrototype(SubType, SuperType);


    var person = new SubType();
    alert(person.sayHi());//hi chan red
該方法最好!

猜你喜欢

转载自blog.csdn.net/chenpeggy/article/details/51243295
今日推荐