【问题标题】:How to implement multiple inheritance using jQuery extend如何使用jQuery扩展实现多重继承
【发布时间】:2013-02-26 19:56:58
【问题描述】:

根据 Douglas Crockford 的说法,我可以使用 http://javascript.crockford.com/prototypal.html 之类的东西(稍作调整)......但我对 jQuery 的处理方式很感兴趣。使用 $.extend 是一种好习惯吗?

我有 4 节课:

            var A = function(){ } 
            A.prototype = {
                name : "A",
                cl : function(){
                    alert(this.name);
                }
            }
            var D = function(){} 
            D.prototype = {
                say : function(){
                    alert("D");
                }
            }

            var B = function(){} //inherits from A
            B.prototype = $.extend(new A(), {
                name : "B"
            });

            var C = function(){} //inherits from B and D
            C.prototype = $.extend(new B(), new D(), {
                name : "C"
            });


            var o = new C();

            alert((o instanceof B) && (o instanceof A) && (o instanceof C)); //is instance of A, B and C 
            alert(o instanceof D); //but is not instance of D

所以,我可以从 A、B、C 和 D 调用每个方法、属性...。问题来了,当我想测试 o 是否是 D 的实例时?我该如何克服这个问题?

【问题讨论】:

  • 请注意,在实践中,在鸭子类型语言中,您很少关心对象是否是某事物的实例。为什么要检查 instanceof D?请注意,通常您真正需要的是en.wikipedia.org/wiki/Mixin
  • 多重继承不适用于instanceof,因为对象只能有一个线性原型链。

标签: javascript jquery multiple-inheritance extend


【解决方案1】:

使用 $.extend 是一种好习惯

$.extend 对于单例很有用,但对于原型并不理想。

使用Object.create(或Crockford 的polyfill),您可以轻松地创建这样的类。我使用$.extend 来简单地处理属性并为它们提供默认值和模块模式,以保持其井井有条。希望这会有所帮助:

// Helper that makes inheritance work using 'Object.create'
Function.prototype.inherits = function(parent) {
  this.prototype = Object.create(parent.prototype);
};

var Person = (function PersonClass() {

  var _defaults = {
    name: 'unnamed',
    age: 0
  };

  function Person(props) {
    $.extend(this, props, _defaults);
  }

  Person.prototype = {
    say: function() {
      return 'My name is '+ this.name;
    }
  };

  return Person;

}());

var Student = (function StudentClass(_super) {

  Student.inherits(_super); // inherit prototype

  var _defaults = {
    grade: 'untested'
  };

  function Student(props) {
    _super.apply(this, arguments); // call parent class
    $.extend(this, props, _defaults);
  }

  Student.prototype.say = function() {
    return 'My grade is '+ this.grade;
  };

  return Student;

}(Person));

var james = new Student({ name: 'James', grade: 5 });

console.log(james instanceof Student); // true
console.log(james instanceof Person); // true

【讨论】:

  • 很好的例子。 tnx。它给了我对事物的新观点。我决定暂时使用此处描述的方法:javascript.crockford.com/prototypal.html。但是有没有办法通过简洁的编码一次使用多重继承?
【解决方案2】:

一个对象只有一个原型,因此不能通过一次调用使其成为其他两种类型的实例。

$.extend(new B(), new D(), ... 创建一个作为 B 实例的对象。然后将 D 的所有属性复制到新创建的对象中。但该对象仍将是 B 的一个实例。

使用$.extend 本身既不好也不坏。但是您必须使用 jQuery,这会降低您的代码的可重用性。而且您必须意识到$.extend 会覆盖具有相同名称的属性,这可能是您想要的,也可能不是您想要的。

【讨论】:

  • 寻求答案!我认为有一种方法可以通过简洁的编码一次使用多重继承?
  • 嗯,多重继承是干净编码的反面;) 如果 instanceof 对您来说不是绝对必要的,那么您的代码就可以了。没办法,抱歉。
  • 你能看看答案吗?如果您可以检查它... 编辑:好的,我无法回答我自己的问题。所以这里是外部链接:jsfiddle.net/Rfzzr
  • 这基本上就是$.extend 所做的。不同之处在于这段代码创建了一个新类型。
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 2020-04-11
  • 2019-05-27
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
相关资源
最近更新 更多