类工厂是指用于生成类的函数,我们不能每写一个类都重复以下代码,要好好封装一下!
var F = function(){} F.prototype = SuperClass.prototype; SubClass.prototype = new F; SubClass.prototype.constructor = SubClass
Prototype.js1.6之后的类工厂
var Animal = Class.create({ initialize: function(name, sound) { this.name = name; this.sound = sound; }, speak: function() { alert(this.name + " says: " + this.sound + "!"); } }); // subclassing Animal var Snake = Class.create(Animal, { initialize: function($super, name) { $super(name, 'hissssssssss'); } }); var ringneck = new Snake("Ringneck"); ringneck.speak(); //-> alerts "Ringneck says: hissssssssss!" var rattlesnake = new Snake("Rattler"); rattlesnake.speak(); //-> alerts "Rattler says: hissssssssss!" // mixing-in Enumerable var AnimalPen = Class.create(Enumerable, { initialize: function() { var args = $A(arguments); if (!args.all( function(arg) { return arg instanceof Animal })) throw "Only animals in here!" this.animals = args; }, // implement _each to use Enumerable methods _each: function(iterator) { return this.animals._each(iterator); } }); var snakePen = new AnimalPen(ringneck, rattlesnake); snakePen.invoke('speak'); //-> alerts "Ringneck says: hissssssssss!" //-> alerts "Rattler says: hissssssssss!"
通过Class.create来创建一个类与连结一个父类与其他材料构成一个子类。想调用同名父方法,需要在此方法的参数中传入一个$super参数。
dojo的类工厂:
var F = function(){} F.prototype = SuperClass.prototype; SubClass.prototype = new F(); SubClassprototype.constructor = SubClass
Prototype.js1.6之后的类定义
dojo.declare( "TestClass", null, { id:"", info: { name : "",age:""}, staticValue:{count:0}, constructor : function(id,name,age) { this.id=id; this.info.name=name; this.info.age=age this.staticValue.count++; } } );
它有三个参数,类名,父类,与一个对象,里面包含构建这个类的材料。
YUI的类工厂
// http://blog.csdn.net/phphot/article/details/4325823 YUI().use('oop', function(Y) { var Bird = function(name) { this.name = name; }; Bird.prototype.getName = function(){ return this.name; }; var Chicken = function(name) { Chicken.superclass.constructor.call(this, name); }; Y.extend(Chicken, Bird); var chicken = new Chicken('Tom'); Y.log(chicken.getName()); });
supperclass 有两个作用:一是可以用来调用父类的方法,二是可以通过 supperclass.constructor 调用父类的构造函数。一举两得.
不过它相对于其他类工厂来说是非常原始的,只负责连结子类与父类。
Simple JavaScript Inheritance
这是jquery作者搞的东西
// http://ejohn.org/blog/simple-javascript-inheritance/ var Person = Class.extend({ init: function(isDancing){ this.dancing = isDancing; }, dance: function(){ return this.dancing; } }); var Ninja = Person.extend({ init: function(){ this._super( false ); }, dance: function(){ // Call the inherited version of dance() return this._super(); }, swingSword: function(){ return true; } }); var p = new Person(true); p.dance(); // => true var n = new Ninja(); n.dance(); // => false n.swingSword(); // => true // Should all be true p instanceof Person && p instanceof Class && n instanceof Ninja && n instanceof Person && n instanceof Class
由Class.create来创建父类,然后通过父类的extend方法加个属性包创建子类.
mootools的类工厂
// http://hmking.blog.51cto.com/3135992/682098 var Animal = new Class({ initialize: function (age) { this.age = age; } }); var Cat = new Class({ Extends: Animal, initialize: function (name, age) { this.parent(age); // calls initalize method of Animal class this.name = name; } }); var cat = new Cat('Micia', 20); console.log(cat.name); // 'Micia' console.log(cat.age); // 20
它应该是所有框架中最复杂也是最强大的,涉及的API就有Mutator Extends Implements还有从Type继承过来的extend implement,它内部拷贝父类属性还用到了深拷贝!
Extends: 可以实现父类,也可以调用父类初始化 this.parent()。而且会覆盖父类定义的变量或者函数。
Implements: 实现父类,子类不可以覆盖父类的方法或者变量。即使子类定义与父类相同的变量或者函数,也会被父类取代掉。
implement: 是用于调整已经创建好的类的原型成员.
extend: 调用子类(非其实例)的extend方法创建一个新的子类.
mass Framework的类工厂
//http://rubylouvre.github.com/doc/index.html $.require("class,spec", function() { var Shape = $.factory({ init: function(len) { $.log(len) this.length = len || 0; }, getLength: function() { return this.length; }, setLength: function(len) { this.length = len; }, getArea: function() { throw "Subclasses must implement this method" } }) var Triangle = $.factory({ inherit: Shape, init: function(len, hei) { //len属性在父类中已定义,这里可以省去 this.height = hei || 0; }, getArea: function() { return this.length * this.height / 2 } }) var Square = $.factory({ inherit: Shape, getArea: function() { return this.length * this.length; } }); var t = new Triangle(3, 4) $.log(t.getArea(), true) var s = new Square(4) $.log(s.getArea(), true) });
$.factory为类工厂,参数为一个普通对象,此对象拥有如下可选属性
- init为新类的构造器,没有默认传入空函数进去
- inherit为新类的父类
- extend的参数是一个对象或对象数组,不管怎么样,这些对象的属性只是为新类添加静态成员,或者说它们是添加到类之上的
- implement的参数是一个对象或对象数组或类(类即函数),这些对象的属性只是为新类添加实例成员,或者说它们是添加到类的原型上.