为什么使用'prototype'进行javascript继承?

时间:2013-03-07 16:12:14

标签: javascript inheritance

JavaScript对象具有'prototype'成员以便于继承。但看起来,我们可以完美地生活,即使没有它,我也想知道,使用它有什么好处。我想知道什么是利弊。

例如,请考虑以下内容(此处为jsfiddle):

function Base (name) {

    this.name = name;
    this.modules = [];
    return this;
}

Base.prototype =
{
    initModule: function() {
        // init on all the modules.
        for (var i = 0; i < this.modules.length; i++)
            this.modules[i].initModule();
        console.log("base initModule");
    }   
};

function Derived(name) {
       Base.call(this,name); // call base constructor with Derived context
}

Derived.prototype = Object.create(Base.prototype);

Derived.prototype.initModule = function () {
      console.log("d init module");
      //  calling base class functionality
      Base.prototype.initModule.call(this);
    }

var derived = new Derived("dname");
console.log(derived.name);
derived.initModule();

一个问题是,为什么要使用'原型'?我们也可以执行Derived = Object.create(Base);

之类的操作 例如

jsfiddle):

Base =
{
    initModule: function() {
        // init on all the modules.
        for (var i = 0; i < this.modules.length; i++)
            this.modules[i].initModule();
        console.log("base initModule",this.name);
    },
    init: function(name) {
        this.name = name; 
        this.modules = [];
    }
};

Derived = Object.create(Base);

Derived.initModule = function () {
      console.log("d init module");
      //  calling base class functionality
      Base.initModule.call(this);
    }
Derived.init("dname");
console.log(Derived.name);
Derived.initModule();

3 个答案:

答案 0 :(得分:3)

如果您不使用原型,则每个类都重新定义方法。也就是说,new Base; new Base; new Base将在第二个示例中创建六个函数。这需要更多的时间和空间。 Derived也将创建自己的功能。

此外,您无法使用原型动态更改每个实例的方法(或添加新方法),这可能会有所帮助 - 尤其是跨模块。

然而,并不是说您应该始终为每种方法使用原型。每种情况都不同。

prototype还允许您在不创建实例的情况下调用不同上下文中的方法(如同类数组对象上的Array.prototype.forEach.call一样)。

答案 1 :(得分:1)

基本上它非常简单,Object.create是Ecmascript 5的一部分,这是一个非常新的。 Prototype从javascript开始就已存在,并且得到了所有浏览器的支持。

因此,只要您需要Internet Explorer 7或8的支持,就不应该依赖于Create。另请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create

(文章还提出了一种使用原型的polyfill; - ))

答案 2 :(得分:-2)

你不需要OO的原型(恕我直言)。

考虑这个继承:

function SubClass()
{
    var object = {};
    object.publicVar = 2;
    object.publicMethod = function SubClassPubMeth()
      {
        return this.publicVar + 2;
      };
    object.poly = function SubClassPoly()
      {
        return 'SubClassPoly';
      };
    return object;
}

function Class()
{
    var object = new SubClass();
    object.classPublicVar = 3;
    object.classPublicMethod =
        function ClassMethod()
        {
            return this.publicVar + this.classPublicVar;
        };
    object.poly = function ClassPoly()
      {
        return 'ClassPoly';
      };
    return object;
}

似乎符合继承法案。

还要考虑这个信息隐藏:

函数类() {     var object = {};     object.x = 3;     var privateVar = 3;     function privateFunction(object)     {       return object.x + privateVar;     }

object.publicFunction = function()
  {
    var priv = privateFunction(this);
    priv += privateVar;
    privateVar = privateVar + 3;
    return priv;
  };
return object;

}

似乎还有信息隐藏技巧(AKA封装)

需要我说更多。