实现代码:
1 function $A (Arguments) {
2 var result = [];
3 for (var i = 0; i < Arguments.length; i++)
4 result.push(Arguments[i]);
5 return result;
6 }
7
8 Class = {
9 create : function () {
10 var args = $A(arguments);
11 var parentClass = args.shift();
12 var properties;
13 if (parentClass instanceof Function)
14 properties = args.shift();
15 else if (parentClass instanceof Object) {
16 properties = parentClass;
17 parentClass = void 0;
18 }
19
20 var klazz = function () {
21 if (this.initialize) this.initialize.apply(this, arguments);
22 };
23
24 if (parentClass) {
25 var tmpClass = new Function;
26 tmpClass.prototype = parentClass.prototype;
27 klazz.prototype = new tmpClass();
28 klazz.prototype.constructor = klazz;
29 }
30
31 for (var key in properties) {
32 if (properties[key] instanceof Function && klazz.prototype[key] instanceof Function) {
33 klazz.prototype[key] = (function () {
34 var _parent = klazz.prototype[key];
35 var _method = properties[key];
36 return function() {
37 var _this = this;
38 $super = function(){
39 _parent.apply(_this, arguments);
40 }
41 _method.apply(this, arguments);
42 }
43 })();
44 }
45 else
46 klazz.prototype[key] = properties[key];
47 }
48
49 return klazz;
50 }
51 }
测试代码:
1
2 T = Class.create({
3 initialize : function (tt,mm) {
4 alert("initialize T");
5 this.tt = tt;
6 this.mm = mm;
7 },
8 l : function () {
9 alert("f");
10 },
11 f : function () {
12 alert(123);
13 }
14 });
15
16 M = Class.create(T, {
17 initialize : function (tt,mm,nn) {
18 $super(tt,mm);
19 alert("initialize M");
20 this.nn = nn;
21 },
22 f : function () {
23 //$super(); 这里也可以不调用父类的f方法
24 alert(456);
25 },
26 s : function () {
27 alert("sssss");
28 }
29 });
30
31 N = Class.create(M);
32
33 m = new N(1,2,3);
34 m.f();
35 m.l();
36 m.s();
37 alert(m.tt);
38 alert(m.mm);
39 alert(m.nn);
40 alert(m instanceof N);
41 alert(m instanceof M);
42 alert(m instanceof T);
在做的过程中,上面粗体部分不是像现在这样实现的,遇到了一个怪异的问题,下面给出原来的实现:
1 var _parent = klazz.prototype[key];
2 var _method = properties[key];
3 klazz.prototype[key] = function() {
4 var _this = this;
5 $super = function(){
6 _parent.apply(_this, arguments);
7 }
8 _method.apply(this, arguments);
9 }
这种实现造成了klazz的prototype中的每个方法执行总是返回相同结果,原因是_parent和_method在create一个Class的
时候已经被固定到properties的最后一个key上,所以在运行的时候会返回相同的结果,解决方法如同上面粗体部分,必须用一个函数封装并立即执行
返回内部函数,这是闭包的一种使用方式,这种做法类似把函数内的内容做一个快照,返回的内部函数存取变量的时候其实是从快照中取得,而不是从
properties中取得。
这个版本并不能用在生产环境中,由于时间仓促,肯定会有BUG或不完善的地方。所以建议大家还是使用Prototype的实现,我这个实现只是用来更加深刻的理解一些概念,比如变量作用域链、闭包等等的使用。