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更容易:
- https://github.com/mbrowne/simpleoo.js (我的库;它的文档阐述了我在这里提到的一些概念)
- https://github.com/Gozala/selfish
- https://github.com/Raynos/pd
笔记:
- 无论何时替换原型(包括扩展),最佳做法是将其构造函数属性设置回正确的构造函数。 这就是我们将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() );