[转帖]Mootools源码分析-12 -- Class
原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-402350
原作者:我佛山人
/*
作为内置类型的Class,使JS的优雅OOP成为可能
因为1519版本有bug,所以以1543版代码为例
*/
var Class = new Native({
//族名,为$type提供精准类型判断
name: 'Class',
//JS way的构造函数,始于Prototype?
initialize: function(properties) {
properties = properties || {};
//真正用于返回的类的原型
var klass = function(empty) {
//复制前先解除关联
for (var key in this) this[key] = $unlink(this[key]);
//复制Class.Mutators的方法,使新类支持实现和继承
for (var mutator in Class.Mutators) {
if (!this[mutator]) continue;
Class.Mutators[mutator](this, this[mutator]);
//已使用,移除
delete this[mutator];
}
this.constructor = klass;
//给构造函数传空函数时直接返回,不作后续处理
if (empty === $empty) return this;
//对于类本身的构造函数,将参数原样传递
var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;
//对于参数中的方法,直接执行,不传递参数
if (this.options && this.options.initialize) this.options.initialize.call(this);
return self;
};
//将Class的特性复制给klass,相当于让klass继承Class
$extend(klass, this);
klass.constructor = Class;
//指定原型
klass.prototype = properties;
return klass;
}
});
//使用继承自Native的implement方法,让新的implement覆盖之
Class.implement({
implement: function() {
Class.Mutators.Implements(this.prototype, Array.slice(arguments));
return this;
}
});
Class.Mutators = {};
/*
使类支持Implements的写法实现
var myClass = new Class({
Implements : [Events, Options],
});
*/
Class.Mutators.Implements = function(self, klasses) {
//$splat使支持多个Implements
$splat(klasses).each(function(klass) {
$extend(self, ($type(klass) == 'class') ? new klass($empty) : klass);
});
};
/*
使类支持Extends的写法继承
var myClass = new Class({
Extends : Base,
});
*/
Class.Mutators.Extends = function(self, klass) {
klass = new klass($empty);
for (var property in klass) {
var kp = klass[property];
var sp = self[property];
self[property] = (function(previous, current) {
//继承出现相同属性、方法时的处理
if ($defined(current) && previous != current) {
var type = $type(current);
if (type != $type(previous)) return current;
switch (type) {
case 'function':
return function() {
//继承出现同名方法时,this.parent可以引用到父类的同名方法
current.parent = this.parent = previous.bind(this);
var value = current.apply(this, arguments);
this.parent = current.parent;
return value;
};
case 'object': return $merge(previous, current);
default: return current;
}
}
return previous;
})(kp, sp);
}
};
作为内置类型的Class,使JS的优雅OOP成为可能
因为1519版本有bug,所以以1543版代码为例
*/
var Class = new Native({
//族名,为$type提供精准类型判断
name: 'Class',
//JS way的构造函数,始于Prototype?
initialize: function(properties) {
properties = properties || {};
//真正用于返回的类的原型
var klass = function(empty) {
//复制前先解除关联
for (var key in this) this[key] = $unlink(this[key]);
//复制Class.Mutators的方法,使新类支持实现和继承
for (var mutator in Class.Mutators) {
if (!this[mutator]) continue;
Class.Mutators[mutator](this, this[mutator]);
//已使用,移除
delete this[mutator];
}
this.constructor = klass;
//给构造函数传空函数时直接返回,不作后续处理
if (empty === $empty) return this;
//对于类本身的构造函数,将参数原样传递
var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;
//对于参数中的方法,直接执行,不传递参数
if (this.options && this.options.initialize) this.options.initialize.call(this);
return self;
};
//将Class的特性复制给klass,相当于让klass继承Class
$extend(klass, this);
klass.constructor = Class;
//指定原型
klass.prototype = properties;
return klass;
}
});
//使用继承自Native的implement方法,让新的implement覆盖之
Class.implement({
implement: function() {
Class.Mutators.Implements(this.prototype, Array.slice(arguments));
return this;
}
});
Class.Mutators = {};
/*
使类支持Implements的写法实现
var myClass = new Class({
Implements : [Events, Options],
});
*/
Class.Mutators.Implements = function(self, klasses) {
//$splat使支持多个Implements
$splat(klasses).each(function(klass) {
$extend(self, ($type(klass) == 'class') ? new klass($empty) : klass);
});
};
/*
使类支持Extends的写法继承
var myClass = new Class({
Extends : Base,
});
*/
Class.Mutators.Extends = function(self, klass) {
klass = new klass($empty);
for (var property in klass) {
var kp = klass[property];
var sp = self[property];
self[property] = (function(previous, current) {
//继承出现相同属性、方法时的处理
if ($defined(current) && previous != current) {
var type = $type(current);
if (type != $type(previous)) return current;
switch (type) {
case 'function':
return function() {
//继承出现同名方法时,this.parent可以引用到父类的同名方法
current.parent = this.parent = previous.bind(this);
var value = current.apply(this, arguments);
this.parent = current.parent;
return value;
};
case 'object': return $merge(previous, current);
default: return current;
}
}
return previous;
})(kp, sp);
}
};