7

JavaScript 对象具有“原型”成员以促进继承。但似乎,即使没有它,我们也可以过得很好,我想知道,使用它有什么好处。我想知道有什么优点和缺点。

例如,考虑以下(此处为 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();
4

3 回答 3

3

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

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

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

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

于 2013-03-07T16:20:37.720 回答
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 ;-))

于 2013-03-07T16:19:10.190 回答
-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 = {}; 对象.x = 3; 变量私有变量 = 3; 函数 privateFunction(object) { return object.x + privateVar; }

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

}

似乎也可以解决信息隐藏(AKA封装)

需要我多说。

于 2013-03-07T16:20:11.463 回答