var arr = [];
var slice = arr.slice;
function create() {
if( arguments.length == 0 || arguments.length > 2 ) throw '参数错误';
//此处两个属性一个是被继承的类,一个为原型方法
var parent = null;
var properties = slice.call(arguments);
//如果第一个参数为类(function),那么就将之取出
if( typeof properties[0] === 'function' )
parent = properties.shift();
properties = properties[0];
//新建类,这个类最好会被返回,构造函数入口为initialize原型方法
function klass() {
this.initialize.apply(this, arguments);
}
//为其指定父类,没有就为空
klass.superclass = parent;
//其子类集合(require情况下不一定准确)
klass.subclasses = [];
//如果存在父类就需要继承
if( parent ) {
//新建一个空类用以继承,其存在的意义是不希望构造函数被执行
//比如 klass.prototype = new parent;就会执行其initialize方法
var subclass = function() {
};
subclass.prototype = parent.prototype;
klass.prototype = new subclass();
parent.subclasses.push(klass);
}
var ancestor = klass.superclass && klass.superclass.prototype;
//遍历对象(其实此处这样做意义不大,我们可以强制最多给两个参数)
//注意,此处为一个难点,需要谨慎,进入addMethods
for( var k in properties ) {
var value = properties[k];
console.log(ancestor,value);
//console.log(k)
//满足条件就重写
if( ancestor && typeof value == 'function' ) {
var argslist = /^\s*function\s*\(([^\(\)]*?)\)\s*?\{/i.exec(value.toString())[1].replace(/\s/i, '').split(',');
//只有在第一个参数为$super情况下才需要处理(是否具有重复方法需要用户自己决定)
if( argslist[0] === '$super' && ancestor[k] ) {
value = (function(methodName, fn) {
//console.log(fn)
return function() {
var scope = this;
var args = [function() {
return ancestor[methodName].apply(scope, arguments);
}];
return fn.apply(this, args.concat(slice.call(arguments)));
};
})(k, value); //1
}
}
klass.prototype[k] = value;
}
if( !klass.prototype.initialize )
klass.prototype.initialize = function() {
};
klass.prototype.constructor = klass;
console.log(new klass())
return klass;
}
以上是继承代码
下面是使用代码
var AbstractView = create({
initialize:function(opts) {
opts = opts || {};
this.wrapper = opts.wrapper || $('body');
//事件集合
this.events = {};
this.isCreate = false;
},
on:function(type, fn) {
if( !this.events[type] ) this.events[type] = [];
this.events[type].push(fn);
},
trigger:function(type) {
if( !this.events[type] ) return;
for( var i = 0, len = this.events[type].length; i < len; i++ ) {
this.events[type][i].call(this)
}
},
createHtml:function() {
throw '必须重写';
},
create:function() {
this.root = $(this.createHtml());
this.wrapper.append(this.root);
this.trigger('onCreate');
this.isCreate = true;
},
show:function() {
if( !this.isCreate ) this.create();
this.root.show();
this.trigger('onShow');
},
hide:function() {
this.root.hide();
}
});
var Alert = create(AbstractView, {
createHtml:function() {
return '<p class="alert">这里是alert框</p>';
}
});
var v1 = new Alert();
v1.show();
var AlertTitle = create(Alert, {
initialize:function($super) {
this.title = '';
$super();
},
createHtml:function() {
return '<p class="alert"><h2>' + this.title + '</h2>这里是带标题alert框</p>';
},
setTitle:function(title) {
this.title = title;
this.root.find('h2').html(title)
}
});
var v2 = new AlertTitle();
v2.show();
v2.setTitle('我是标题');
var AlertTitleButton = create(AlertTitle, {
initialize:function($super) {
this.title = '';
$super();
this.on('onShow', function() {
var bt = $('<input type="button" value="点击我" />');
bt.click($.proxy(function() {
alert(this.title);
}, this));
this.root.append(bt)
});
}
});
var v3 = new AlertTitleButton();
v3.show();
v3.setTitle('我是标题和按钮的alert');
-----分隔线啦啦啦-----
value = (function(methodName, fn) {
//console.log(fn)
return function() {
var scope = this;
var args = [function() {
return ancestor[methodName].apply(scope, arguments);
}];
return fn.apply(this, args.concat(slice.call(arguments)));
};
})(k, value);
在上面这个代码段里面
fn.apply(this, args.concat(slice.call(arguments)))这句话的意思是说执行fn函数,但是argument明明是空值 为什么还要去合并数组args.concat(slice.call(arguments)),而且上面那整段代码都不是很理解,请大大指教,thx :)