簡體   English   中英

將原型添加到現有對象

[英]Add prototype to existing object

我想使用Javascript做一些繼承。 問題是我不知道如何在繼承的對象上保留A類原型。

這是我的代碼:

function Base() {
    this.attribute1 = null;
}

Base.prototype = {
    baseFunction: function() {}
};

function SubBase()
{
    Base.call(this); // Constructor call
    this.baseFunction();
    this.subBaseFunction();
}

SubBase.prototype = Base.prototype;
SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
}

通過這種方式,我擦除了Base.prototype但我不想這樣做。

我嘗試了SubBase.prototype.__proto__ = Base.prototype; 但是它顯然太慢了

我知道我可以做(但是寫的時間太長了,對我來說還不算干凈):

SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};

我該如何做/更好地編寫它?

代替這個:

SubBase.prototype = Base.prototype;
SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
}

您需要將每個其他方法添加到現有的原型對象上,以避免覆蓋您剛才放置的Base.prototype

// establish the prototype we're inheriting from
// make a new object into the prototype so when we change it, it 
// doesn't change the original
SubBase.prototype = Object.create(Base.prototype);

// now add more methods onto the inherited prototype
SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};

注意:您也不想只分配Base.prototype因為當您更改SubBase.prototype ,實際上您將同時更改兩個對象(對象分配只是一個引用)。 所以在這里,我正在使用Object.create(Base.prototype)創建該原型的副本。


許多庫支持某種extend()函數,該函數將屬性從一個對象復制到另一個對象。 這樣一來,您可以定義一個單獨的方法對象,然后將其“添加”到現有的原型中,但是此功能不是純JavaScript內置的。

例如在jQuery中,您可以執行以下操作:

// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);

jQuery.extend(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

或者, 在2016年更新 ,ES6包含一個Object.assign()函數 ,該函數會將屬性從一個對象復制到另一個對象:

Object.assign(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

或者,您可以創建自己的函數,僅用幾行代碼即可將屬性從一個對象復制到另一個對象。


或者,在純JavaScript中使用相同的代碼:

// copy properties from src to target
function copyProperties(target, src) {
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            target[prop] = src[prop];
        }
    }
    return(target);
}

// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);

copyProperties(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

這是我通常使用的樣式:

function Base() {
    this.attribute1 = null;
}

Base.prototype = {
    baseFunction: function() {}
};

function SubBase()
{
    Base.apply(this, arguments); // Constructor call with arguments
}

(function() {
    var proto = SubBase.prototype = Object.create(Base.prototype);
    proto.constructor = SubBase;
    proto.subBaseFunction = function() {
        // code here
    };
    proto.subBaseOtherFunction = function() {
        // code here
    };
})();

首先,您實際上並沒有從Base繼承……您只是向其中添加了功能。

SubBase.prototype = Base.prototype;
SubBase.prototype.foo = true;
alert(Base.prototype.foo);

要設置繼承鏈,您需要分配一個base實例作為原型:

SubBase.prototype = new Base();

然后像在帖子中一樣對它進行擴充:

SubBase.prototype.newFunction = function () { };

這種方式進行繼承的一個缺點是基類構造函數無法接收參數。 如果需要,則需要使用Object.create來設置繼承,並手動調用基類構造函數:

function Base(x) {
    alert(x);
};
Base.prototype.baseFunction = function () {
    alert('called method from base class');
};

function SubBase(x) {
    Base.call(this, x);
};
SubBase.prototype = Object.create(Base.prototype);

var instance = new SubBase(1);
instance.baseFunction();

您可以為此使用jQuery.extend():

SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
};

$.extend(SubBase.prototype, Base.prototype);

請參閱: http//jsfiddle.net/dd6UC/

jQuery.extend()文檔: http : //api.jquery.com/jquery.extend/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM