1. 程式人生 > >[筆記]javascript面向物件

[筆記]javascript面向物件

1.繼承模式1

繼承的本質即將子類的prototype指向父類即可。

function subType() {
            if (!arguments.callee.prototype.subSay) {
                arguments.callee.prototype.say = function () {
                    alert('sub_hello_' + this.name);
                }
            }
            this.name = 'aa';
        }

        function superType() {
            if (!arguments.callee.prototype.superSay) {
                arguments.callee.prototype.superSay = function () {
                    alert('super_hello_' + this.name);
                }
            }
            this.name = 'bb';
            this.color = ['red', 'black'];
        }

        subType.prototype = new superType(); //改寫了指向,之前的所有原型成員無法繼續引用

        var t1 = new subType();
        //t1.subSay();//報錯,無subSay方法
        t1.superSay(); //super_hello_aa  例項屬性遮蔽了原型屬性
        var t2 = new subType();
        t2.color.push('orange');
        alert(t2.color); //red,black,orange 
        alert(t1.color); //red,black,orange 此時color是subType的原型屬性,所以值的改動會影響到所有例項
優點:可以引用父類superType的所有例項成員與原型成員。

缺點:當父類superType的例項屬性為引用型別時,如superType.color,任意子類的例項對其值的改動都會影響到所有例項。

2.繼承模式2

在1的基礎上,利用建構函式將父類的例項屬性新增到子類中

function subType(name, age) {
            superType.apply(this, arguments);
            this.name = name;
        }

        function superType(name, age) {
            if (!arguments.callee.prototype.superSay) {
                arguments.callee.prototype.superSay = function () {
                    alert('super_hello_' + this.name);
                }
            }
            this.name = 'bb';
            this.color = ['white', 'black'];
        }

        subType.prototype = new superType(); 

        var t1 = new subType();
        var t2 = new subType();
        t2.color.push('orange');
        alert(t2.color); //red,black,orange 
        alert(t1.color); //red,black 實為子類的例項屬性
優點:在子類的建構函式中呼叫父類的建構函式,將父類的例項屬性建立到子類中,在最終引用時實際是引用子類的例項屬性,避免了1的問題。

缺點:在使用原型繼承時:subType.prototype  = new superType()這個過程中實際上又將父類的例項屬性新增到了子類的prototype原型物件中,造成了不必要的資源浪費。

3.繼承模式3

使用建構函式繼承父類的例項屬性,使用子類的原型繼承父類的原型

function subType(name, age) {
            superType.apply(this, arguments);
            this.name = name;
        }

        function superType(name, age) {
            if (!arguments.callee.prototype.superSay) {
                arguments.callee.prototype.superSay = function () {
                    alert('super_hello_' + this.name);
                }
            }
            this.name = 'bb';
            this.color = ['white', 'black'];
        }

        //建立一個指定物件的子類例項,該例項的原型指向父類
        function createSubType(superType) {
            var subType = function () { };
            subType.prototype = superType;
            return new subType();
        }

        //實現原型繼承
        function inheritPrototype(subType, superType) {
            var prototype = createSubType(subType.prototype);
            prototype.constructor = subType;
            subType.prototype = prototype;
        }

        inheritPrototype(subType, superType);

        var t1 = new subType();
        var t2 = new subType();
        t2.color.push('orange');
        alert(t2.color); //red,black,orange 
        alert(t1.color); //red,black