類工廠是指用於生成類的函數,我們不能每寫一個類都重復以下代碼,要好好封裝一下!
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的參數是一個對象或對象數組或類(類即函數),這些對象的屬性只是為新類添加實例成員,或者說它們是添加到類的原型上.