簡體   English   中英

在JavaScript中有繼承的“正確”方法嗎?如果是這樣,它是什么?

[英]Is there a “right” way to do inheritance in JavaScript? If so, what is it?

我一直在努力學習如何為現有代碼添加測試 - 目前閱讀閱讀閱讀有效使用遺留代碼 我一直在嘗試在JavaScript中應用一些原則,現在我正在嘗試提取一個接口。

在JavaScript中搜索創建接口時,我找不到很多 - 我發現繼承的內容似乎有幾種不同的方式。 (有些人創建自己的基類,以提供有用的方法,使其更容易進行繼承,有些使用函數,有些使用原型)。

什么是正確的方法? 有一個簡單的例子用於在JavaScript中提取界面?

沒有明確的正確方法 ,因為有很多人在做很多不同的事情。有很多有用的模式。

克羅克福德建議你“順其自然”,或者以與javascript的原型性質相對應的方式編寫javascript。

當然,他繼續表明Netscape建議的原始模型實際上已經被破壞了。 他將其標記為“偽經典”,並指出了遵循該模型所涉及的許多誤導和不必要的復雜性。

他將“對象”函數編寫為補救措施(現在稱為Object.create())。 它允許一些非常強大的原型模式。

當你必須使用傳統的javascript時,開發一個干凈的界面並不總是那么容易,尤其是當你處理大型系統時,通常包括多個庫,每個系統都實現了獨特的風格和不同的繼承模式。 一般來說,我要說繼承的“正確方法”是允許你編寫一個干凈的接口,它在遺留代碼的上下文中表現良好,但也允許你重構並消除舊的依賴關系。 。

考慮到主要庫模式之間的差異,我發現在我自己的工作中最成功的路徑是保持我的接口完全獨立於庫接口。 如果它有用,我將使用庫或模塊,但不會受其約束。 這使我能夠重構大量代碼,逐步淘汰一些庫,並使用庫作為腳手架,以后可以進行優化。

沿着這些方向,我編寫了受Crockford寄生繼承模式啟發的界面。 這真的是簡單的勝利。

另一方面,我確信您可以爭取選擇一個庫,在整個團隊中執行它,並遵守其繼承模式和接口約定。

javascript中沒有類,只有對象。
但是如果你堅持模仿基於類的面向對象模型,你可以使用:

function ChildClass() {
    ParentClass.call(this);
    // Write the rest of your constructor function after this point.
};
ChildClass.prototype = jQuery.extend({}, ParentClass.prototype, ChildClass.prototype);

jQuery.extend是jQuery庫中的“淺拷貝”函數。 您可以將其替換為任何其他對象復制/克隆功能。

你正在看兩件不同的事情。

首先你有接口。 實現這一目標最常被接受的方式是Duck Typing(“如果它看起來像鴨子,嘎嘎叫像鴨子那么它就是鴨子”)。 這意味着如果一個對象實現了一組接口方法,那么它就是那個接口。 您可以通過定義一個接口的方法名數組來實現它。 然后檢查一個對象是否實現了那個interfece,你看它是否實現了那些方法。 這是一個我掀起的代碼示例:

function Implements(obj, inter)
{
    var len = inter.length, i = 0;
    for (; i < len; ++i)
    {
        if (!obj[inter[i]])
            return false;
    }
    return true;
}

var IUser = ["LoadUser", "SaveUser"];

var user = {
        LoadUser : function()
        {
            alert("Load");
        },

        SaveUser : function()
        {
            alert("Save");
        }
    };

var notUser = {
        LoadUser : function()
        {
            alert("Load");
        }
    };

alert(Implements(user, IUser));
alert(Implements(notUser, IUser));

現在你有了繼承權。 JS沒有內置的繼承; 所以你必須手動實現它。 這只是將一個對象的屬性“復制”到另一個對象的問題。 這是另一個代碼示例(不完美,但它證明了這一點):

function InheritObject(base, obj)
{
    for (name in base)
    {
        if (!obj[name])
            obj[name] = base[name];
    }
}

var Base = {
        BaseFunc : function() { alert("BaseFunc from base"); },
        InheritFunc : function() { alert("InheritFunc from base"); }
    }

var Inherit = {
        InheritFunc : function() { alert("InheritFunc from inherit"); },
        AnotherFunc : function() { alert("AnotherFunc from inherit"); }
    }

InheritObject(Base, Inherit);

Inherit.InheritFunc();
Inherit.BaseFunc();
Inherit.AnotherFunc();

Base.BaseFunc();
Base.InheritFunc();

你可能想看看http://www.mootools.net 它有我最喜歡的Classes實現。 你也一定想看看“Pro Javascript Design Patterns”

http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X

本書詳細介紹了如何在javascript中模擬OOP。

還可以查看Dean Edwards的Base.js. 你可以看看它在這里的博客文章是不言自明。

Prototype提供了自己的繼承,來自http://www.prototypejs.org/api/class/create

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },

  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});

// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});

暫無
暫無

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

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