實現代碼:
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的實現,我這個實現只是用來更加深刻的理解一些概念,比如變量作用域鏈、閉包等等的使用。