最近在用javascript,没有类用着挺不顺手,所以写了个面向对象支持的方法,用法如下:
class.js 支持javascript类定义
(function() {
if (!Function.prototype.bind) {
Function.prototype.bind = function(me) {
var other = this;
return function() {
return other.apply(me, Array.prototype.slice
.call(arguments));
};
};
}
function _createObject(parent, name) {
if (parent[name] == undefined) {
parent[name] = {}
}
return parent[name];
}
function _cloneMember(dest, src) {
if (src == null) {
return;
}
for ( var m in src) {
dest[m] = src[m];
}
}
function _cloneMemberMethod(dest, src) {
if (src == null) {
return;
}
for ( var m in src) {
if (typeof src[m] == "function") {
dest[m] = src[m];
}
}
}
function _cloneMemberVar(dest, src) {
if (src == null) {
return;
}
for ( var m in src) {
if (typeof src[m] != "function") {
dest[m] = src[m];
}
}
}
function _constructorBroker() {
}
Namespace = {
define : function(namespace, _class) {
if (namespace != "") {
var className = _class._className();
if (undefined == window[className]) {
throw "could not find class " + className;
}
window[className] = undefined;
_class.prototype._className = _class._className = function() {
return namespace + '.' + className;
}
var nsObject = window;
var nsArray = namespace.split('.');
for (var i = 0; i < nsArray.length; ++i) {
nsObject = _createObject(nsObject, nsArray[i]);
}
nsObject[className] = _class;
}
}
};
Class = {
define : function(className, constructor, members, staticMembers) {
function _class(broker) {
if (!(broker instanceof _constructorBroker)) {
_cloneMemberVar(this, members);
var argues = Array.prototype.slice.call(arguments);
constructor.apply(this, argues);
}
}
window[className] = _class
_class.prototype = {};
_cloneMemberMethod(_class.prototype, members);
_cloneMember(_class, staticMembers);
_class.prototype._className = _class._className = function() {
return className;
}
_class.prototype._class = function() {
return _class;
}
return _class;
},
extend : function(_super, className, constructor, members,
staticMembers) {
function _extend(broker) {
var superFuncObject = {_super : _extend.prototype._super};
// for ( var mf in _super.prototype) {
// if (typeof _super.prototype[mf] == "function") {
// superFuncObject[mf] = _super.prototype[mf].bind(this);
// }
// }
superFuncObject._invoke = function(me, funName){
var argues = Array.prototype.slice.call(arguments);
argues.splice(0, 2);
return _super.prototype[funName].apply(me, argues);
}
if (!(broker instanceof _constructorBroker)) {
var argues = Array.prototype.slice.call(arguments);
_super.apply(this, argues);
this._super = superFuncObject;
_cloneMemberVar(this, members);
constructor.apply(this, argues);
}
if (undefined == this._super) {
this._super = superFuncObject;
}
}
window[className] = _extend;
_extend.prototype = new _super(new _constructorBroker());
_cloneMemberMethod(_extend.prototype, members);
_cloneMember(_extend, staticMembers);
_extend.prototype._className = _extend._className = function() {
return className;
}
_extend.prototype._class = function() {
return _extend;
}
return _extend;
}
};
})();
使用实例:
Namespace.define("std", Class.define("vector", function() {
this.mContainer = [];
}, {
back : function() {
if (this.mContainer.length > 0) {
return this.mContainer[this.mContainer.length - 1];
}
return null;
},
pop : function() {
if (this.mContainer.length > 0) {
return this.erase(this.mContainer.length - 1);
}
return null;
},
push : function(e) {
this.mContainer.push(e);
return this;
},
erase : function(index, count) {
if (count != undefined) {
return this.mContainer.splice(index, count);
}
return this.mContainer.splice(index, 1)[0];
},
find : function(item) {
for (var i = 0; i < this.mContainer.length; i++) {
if (this.mContainer[i] == item){
return i;
}
}
return -1;
},
reverse : function () {
var newContainer = new std.vector();
for (var i = 0; i < this.mContainer.length; i++) {
newContainer.insert(0, this.mContainer[i]);
}
this.mContainer = newContainer.toArray();
return this;
},
insert : function(index, item) {
this.mContainer.splice(index, 0, item);
return this;
},
size : function() {
return this.mContainer.length;
},
get : function(index) {
return this.mContainer[index];
},
set : function(index, e) {
this.mContainer[index] = e;
return this;
},
sort : function(callback) {
this.mContainer.sort(callback);
return this;
},
contains : function(obj) {
return this.find(obj) >= 0;
},
concat : function(arr) {
if (arr instanceof Array) {
this.mContainer = this.mContainer.concat(arr);
}
else if (arr instanceof std.vector){
this.mContainer = this.mContainer.concat(arr.container);
}
return this;
},
toArray : function(){
return this.mContainer;
},
isEmpty : function() {
return this.mContainer.length == 0;
}
}));
Namespace.define("std", Class.extend(std.vector, "queue", function(){
}, {
enqueue : function(item){
this.push(item);
return this;
},
dequeue : function() {
if (!this.isEmpty()) {
return this.erase(0)
}
return null;
},
peek : function() {
if (!this.isEmpty()) {
return this.get(0)
}
return null;
},
push : function(e) {
//通过 _super对象的_invoke方法可以调用基类的方法
return this._super._invoke(this, "push", e);
},
}, {}))
//调用方法
var vec = new std.vector();
vec.push(123);
var que = new std.queue();
que.enqueue("123");