【问题标题】:Pros and cons of inheritance modeling in Javascript?Javascript中继承建模的优缺点?
【发布时间】:2011-05-04 13:21:13
【问题描述】:

我意识到 Javascript 没有类,也不是为了具有经典的 OOP 继承而构建的。但我发现这样的模式非常有用,因此我想构建一种简单的方法来模拟这种行为,理想情况下,同时利用 Javascript 灵活性的最佳部分。以下方法的优缺点是什么?

我的自定义库中有以下函数:

function inherit(superClass, args, instance) {
    var subClass = inherit.caller;
    var o = new superClass(args);
    for(p in o) {
        if(o.hasOwnProperty(p)) init(instance, p, o[p]);
        else init(subClass.prototype, p, o[p]);
    }
}

function isUndefined(x) {var u; return x === u;}

// sets p to value only if o[p] is undefined
function init(o, p, value) {if(isUndefined(o[p])) o[p] = value;}

此设置需要两个约定:

  1. 作为建模类的函数必须采用一个参数:具有命名属性的对象
  2. 希望从另一个“继承”的函数必须调用继承函数。

这是您得到的结果示例(粘贴到 Firebug 命令行以及库函数中,以查看它的运行情况):

function SuperClass(args) {
  this.x = args.x;
}

SuperClass.prototype.p = 'SuperClass prototype property p';

function SubClass(args) {
  inherit(SuperClass, args, this);
  this.y = args.y;
}

SubClass.prototype.q = 'SubClass prototype property q';

var o = new SubClass({
  x: 'x set in SuperClass',
  y: 'y set in SubClass'
});

console.dir(o);  // correctly has properties x, y, p, and q

['x', 'y', 'p', 'q'].forEach(function(prop) {
  // true for x and y, false for p and q
  console.log("o.hasOwnProperty('" + prop + "')", o.hasOwnProperty(prop));
});

console.log("o instanceof SubClass: ", o instanceof SubClass);      // true
console.log("o instanceof SuperClass: ", o instanceof SuperClass);  // false

我知道以下缺点:

  1. 修改超类原型不会影响您的实例对象,正如您对原型样式继承所期望的那样
  2. 实例对象不会注册为超类的实例(尽管它仍然会像一个一样)
  3. 参数约定可能很烦人

和优点:

  1. 只需要一个函数调用(易于实现)
  2. 原型属性和实例属性的区别
  3. 传递给子类的参数也会传递给超类
  4. 由超类构造函数设置的实例属性在子类构造函数中立即可用
  5. 多重继承很简单,只需在子类中多次调用inherit
  6. 不会覆盖子类的现有属性

优点 3 - 6 使这种方法对我来说比 SubClass.prototype = new SuperClass() 方法更有用。其他方法,比如 dojo 的类建模,要复杂得多,我认为没有必要。

所以,告诉我你的想法。如果其他人以前这样做过,请告诉我,我无意重复任何想法。

【问题讨论】:

  • 请记住caller 是非标准的,在严格模式的 ES5 中访问它会引发错误
  • 到目前为止我最喜欢的解决方案是coffeescript! jashkenas.github.com/coffee-script

标签: javascript oop inheritance prototype-programming


【解决方案1】:

那些来这里看看在 javascript 中进行继承的简单且可能是最好的方法的人请阅读以下内容,它比我浏览过的所有其他内容都简单得多:

http://javascript.crockford.com/prototypal.html

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

注意:Object.create 现在是新浏览器中 javascript 的一部分,但通过添加上述内容,以下内容也适用于旧浏览器。

newObject = Object.create(oldObject);

【讨论】:

    【解决方案2】:

    您可能想看看 John Resig 对 JavaScript 继承所做的工作:http://ejohn.org/blog/simple-javascript-inheritance/

    这是我见过的最好的 Javascript 继承尝试。

    【讨论】:

      【解决方案3】:

      你知道你发布的内容的缺点......所以看看我的博客,了解我认为最好的方法,同时描述其他模式的缺陷

      http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

      例子:

      //Abstraxct base class
      function Animal(name) {
        this.name = name;
      }
      
      Animal.prototype.sayMyName = function () {
        console.log(this.getWordsToSay() + " " + this.name);
      }
      
      Animal.prototype.getWordsToSay = function () {} // abstract
      
      // --------------------------------
      
      function Dog(name) {
        // Call the parent's constructor
        Animal.call(this, name);
      }
      
      extend(Dog, Animal, {
        getWordsToSay: function(){
          return "Ruff Ruff";
        }
      });
      

      我发布的代码是一个示例语法。博客文章详细介绍了如何添加语法糖。

      重要的是:

      • new Dog("Lassie") instanceof Animal // true
      • 不只是为了设置继承而调用 Animal 构造函数
      • var dog = new Dog("Lassie"); Animal.prototype.blah = 5;狗.blah == 5; //输出真

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-29
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        • 2013-10-31
        相关资源
        最近更新 更多