上篇解决了之前的继承中调用uber()的一些问题,此篇可以封装上篇篇尾所述的一些缺陷。声明函数部分是无法封装的。
var create = function () {
var X = function () {};
X.inherits(Base);
return X;
};
通过这个函数获得的构造函数都是同一个。但可以封装剩下两步骤,并构建自己的基类型。
尽管都指向的是函数中的引用,构造函数的名称也都是X,但永远不会是同一个。真是有点无地自容。
// 命名空间
var X = {};
// 提供对象扩展方法
X.extend = function (target, source) {
var i = '';
for (i in source) {
if ( source.hasOwnProperty(i) ) {
target[i] = source[i];
}
}
return target;
};
// 基类
X.Base = function () {};
X.Base.baseMethods = {
// 此处指定必须拥有的方法
log : function () {
console.log('Hey,');
}
};
X.Base.prototype = X.extend({
// 其他属性和方法
}, X.Base.baseMethods);
Function.method('extendFrom', function (Parent, obj) {
this.inherits(Parent);
// 强制设置必须拥有的方法 当然最好可以靠约定 不过约定有时并不可靠
X.extend(this.prototype, X.Base.baseMethods);
X.extend(this.prototype, obj);
return this;
});
测试:
X.A = function () {};
X.B = function () {};
X.C = function () {};
X.A.extendFrom(X.Base, {
log : function () {
this.uber('log');
console.log('What\'s');
}
});
X.B.extendFrom(X.A, {
log : function () {
this.uber('log');
console.log('up');
}
});
X.C.extendFrom(X.B, {
log : function () {
this.uber('log');
console.log('!');
}
});
( new X.C() ).log();
// 或者在项目中 可以这样
window.pageData = {
pageId : 'C'
};
X.init = function () {
( new X[window.pageData.pageId] () ).log();
};
X.init();