jquery类inheritance

var A=function(){ }; $.extend(A.prototype, { init:function(){ alert('A init'); } }); var B=function(){ }; $.extend(B.prototype,A.prototype,{ init:function(){ alert('B init'); } }); var p=new A(); p.init(); var x=new B(); x.init(); 

上面是在jQuery中创建类和inheritance的最佳方法吗? 在B的init中如何调用父的init(类似于OO语言中的super.init())?

对于OO,最好在jQuery之外查看。 jQuery基于选择器返回的集合。

如果你想要类,一些选择是Base2 , Joose和JS.Class 。

John Resig在这里创建了一个简单inheritance的片段。 http://ejohn.org/blog/simple-javascript-inheritance/

他将超类存储到_super变量中,因此您可以像这样调用它

 this._super(); 

你可以参考他的代码片段,以更好地了解他的另一个有用的post: http : //alexsexton.com/?p = 51

如何调用父方法:

 var B=function(){ A.call(this); }; $.extend(B.prototype,A.prototype,{ init:function(){ A.prototype.init.call(this); alert('B init'); } }); 

如果您不想依赖任何其他库,则可以执行以下操作:

 function A() {} A.prototype.foo = function() {}; function B() { A.call(this); //Or, if there are arguments that need to be passed to A(), //this might be preferable: //A.apply(this, arguments); } B.prototype = new A(); //Or, if the browser supports ECMAScript 5 and/or you have a shim for Object.create, //it would be better to do this: B.prototype = Object.create(A.prototype); $.extend(B.prototype, { //set the constructor property back to B, otherwise it would be set to A constructor: B, bar: function() {} }); 

确保在构造函数中定义任何属性,而不是在原型上定义,例如:

 function A() { this.baz = null; } 

这避免了无意中共享的原型属性。

有一些库使原型inheritance更容易:

笔记:

  • 无论何时替换原型(包括扩展),最佳做法是将其构造函数属性设置回正确的构造函数。 这就是我们将B.prototype.constructor设置为B的原因。如果您要替换A.prototype,您应该这样做:

 A.prototype = { constructor: A, foo: function() {} //other methods... } 
  • B.prototype = Object.create(A.prototype)B.prototype = new A()B.prototype = new A()因为如果你忘了从B()的构造函数调用A(),它会帮助你提早检测它; 它还允许A()具有所需的参数。 旧版浏览器需要垫片; 最简单的垫片(尽管它不支持完整的Object.create规范)位于本页底部: http : //javascript.crockford.com/prototypal.html 。

我使用相同的模式,我喜欢它的简洁。

关于缺乏“超级”关键字,这不是一个真正的问题。 感谢Function.prototype.call()运算符,您可以在任何对象的上下文中调用任何函数。 所以从B.prototype.init()调用A.prototype.init()的顺序是:

A.prototype.init.call(this, some parameters ...);

另外,不要忘记您可以从B构造函数中调用A构造函数,如下所示:

 B = function(key, name) { A.call(this, key); this.name = name; }; 

一个经过实验的JS编码器会知道会发生什么。

所以总结:不完美但足够接近。

我在寻找类似的东西。 所给出的答案都没有真正吸引我,所以我终于自己解决了这个问题……

http://jsfiddle.net/tn9upue0/1/

示例类

  • $ .Animal()创建一个通用动物,默认为4个腿,可以在其选项中传递一个名称,并且可以自我描述。 $ .Dog()是Animal的一个子类,它是“woof”,并且可能知道一些技巧。 $ .Cat()是Animal的一个子类,它“喵”。 $ .Bird()是Animal的一个子类,它有两条腿并且是“tweet”。

类实现

  • 每个动物子类都创建一个名为parent的$ .Animal实例,稍后可以使用它来调用父类的方法。 调用父方法时,上下文可能很重要。 如果是,则应通过$ .proxy()调用该方法作为上下文。

示例输出

我的名字不详。 我是一条有四条腿的动物。

我叫罗孚。 我是一条有四条腿的动物。 我说“woof”。 我可以坐着,停留,翻身。

我的名字是连指手套。 我是一条有四条腿的动物。 我说“喵”。

我的名字不详。 我是一条有两条腿的动物。 我说“推特”。

示例代码

 $.Animal = function (options) { return { options: options || {}, _getName: function () { return this.options.name || 'unknown'; }, _getLegs: function () { return 4; }, describe: function () { return 'My name is ' + this._getName() + '. I am an animal with ' + this._getLegs() + ' legs.'; } } }; $.Dog = function (options) { var parent = $.Animal(options); return $.extend({}, parent, { describe: function () { var s = $.proxy(parent.describe, this)() + ' I say "woof".'; if (this.options.tricks) { s += ' I can ' + this.options.tricks + '.'; } return s; } }); }; $.Cat = function (options) { var parent = $.Animal(options); return $.extend({}, parent, { describe: function () { return $.proxy(parent.describe, this)() + ' I say "meow".'; } }); }; $.Bird = function (options) { var parent = $.Animal(options); return $.extend({}, parent, { _getLegs: function () { return 2; }, describe: function () { return $.proxy(parent.describe, this)() + ' I say "tweet".'; } }); }; var animal = $.Animal(), rover = $.Dog({name: 'Rover', tricks: 'sit, stay, and roll over'}), mittens = $.Cat({name: 'Mittens'}), bird = $.Bird(); $('#out').html( animal.describe() + '
' + rover.describe() + '
' + mittens.describe() + '
' + bird.describe() );