终于到java的关键字package,import,extends,class,new实现了一遍。
代码为证:
var Js5 = {version:"5.0.0"};
var __cpackage__;
var __gclasses__ = {};
var __iclasses__ = {};
var __imports__ = [];
Js5.apply = function(o, c) {
if (o && c && typeof c == 'object') {
for (var p in c) {
o[p] = c[p];
}
}
return o;
};
(function() {
var toString = Object.prototype.toString,
oc = Object.prototype.constructor;
Js5.apply(Js5, {
applyIf : function(o, c) {
if (o) {
for (var p in c) {
if (!Js5.isDefined(o[p])) {
o[p] = c[p];
}
}
}
return o;
},
override: function(origclass, overrides) {
if (overrides) {
var p = origclass.prototype;
Js5.apply(p, overrides);
}
},
/*override : function(origclass, overrides) {
if (overrides) {
var p = origclass.prototype;
overrides = overrides(p.superclass);
Js5.apply(p, overrides);
if (Js5.isIE && overrides.hasOwnProperty('toString')) {
p.toString = overrides.toString;
}
}
},*/
isFunction : function(v) {
return toString.apply(v) === '[object Function]';
},
isString : function(v) {
return typeof v === 'string';
},
isBoolean : function(v) {
return typeof v === 'boolean';
},
isElement : function(v) {
return !!v && v.tagName;
},
isDefined : function(v) {
return typeof v !== 'undefined';
},
isObject : function(v) {
return !!v && Object.prototype.toString.call(v) === '[object Object]';
},
isDate : function(v) {
return toString.apply(v) === '[object Date]';
},
isPrimitive : function(v) {
return Js5.isString(v) || Js5.isNumber(v) || Js5.isBoolean(v);
},
isNumber : function(v) {
return typeof v === 'number' && isFinite(v);
},
isEmpty : function(v, allowBlank) {
return v === null || v === undefined || ((Js5.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
},
isArray : function(v) {
return toString.apply(v) === '[object Array]';
},
isIterable : function(v) {
//check for array or arguments
if (Js5.isArray(v) || v.callee) {
return true;
}
//check for node list type
if (/NodeList|HTMLCollection/.test(toString.call(v))) {
return true;
}
//NodeList has an item and length property
//IXMLDOMNodeList has nextNode method, needs to be checked first.
return ((typeof v.nextNode != 'undefined' || v.item) && Js5.isNumber(v.length));
},
each : function(array, fn, scope) {
if (Js5.isEmpty(array, true)) {
return [];
}
if (!Js5.isIterable(array) || Js5.isPrimitive(array)) {
array = [array];
}
for (var i = 0, len = array.length; i < len; i++) {
if (fn.call(scope || array[i], array[i], i, array) === false) {
return i;
}
}
return [];
},
namespace : function() {
var o, d;
Js5.each(arguments, function(v) {
d = v.split(".");
o = window[d[0]] = window[d[0]] || {};
Js5.each(d.slice(1), function(v2) {
o = o[v2] = o[v2] || {};
});
});
return o;
},
nameclass:function(c) {
if (__gclasses__[c]) return __gclasses__[c];
var d = c.split(".");
var o = window[d[0]] = window[d[0]] || {};
Js5.each(d.slice(1, d.length - 1), function(v2) {
o = o[v2] = o[v2] || {};
});
return __gclasses__[c] = o[d[d.length - 1]];
},
importclass:function(c) {
if (__gclasses__[c]) return __gclasses__[c];
if (__iclasses__[c]) return __iclasses__[c];
var d = c.split(".");
var o = window[d[0]] = window[d[0]] || {};
var name = d[d.length - 1];
Js5.each(d.slice(1, d.length - 1), function(v2) {
o = o[v2] = o[v2] || {};
});
if (o[name]) {
o = __gclasses__[c] = o[name];
} else {
Js5.each(__imports__, function(i) {
if ((o = i[name])) {
return false;
}
});
__iclasses__[c] = o;
}
return o;
}
});
})();
/**
* p1:String ==>package name
* p2..p-1,Object ==>imports
* p-1,function ==> package body
*/
function jpackage() {
var l = arguments.length,i = 0;
if (l == 0) return;
var pkf = arguments[l - 1];
pkf.$Define = true;
if (Js5.isString(arguments[0])) {
__cpackage__ = Js5.namespace(arguments[0]);
i = 1;
} else {
__cpackage__ = window;
i = 0;
}
var args = [],vs,ip;
Js5.each(Array.prototype.slice.call(arguments, i, l - 1), function(v) {
if (Js5.isString(v)) {
vs = v.split(";");
Js5.each(vs, function(v2) {
if (v2.substr(-2) == ".*") {
ip = Js5.namespace(v2.substring(0, v2.length - 2));
__imports__.push(ip);
args.push(ip);
} else {
args.push(Js5.importclass(v2));
}
});
} else if (Js5.isArray(v)) {
args = args.concat(v);
} else {
args.push(v);
}
});
pkf.apply(__cpackage__, args);
__cpackage__ = null;
__imports__ = [];
__iclasses__ = {};
}
function jimport() {
var args = [],vs,ip;
__imports__ = [];
__iclasses__ = {};
if (jimport.caller) {
jimport.caller.$Define = true;
}
Js5.each(arguments, function(v) {
if (Js5.isString(v)) {
vs = v.split(";");
Js5.each(vs, function(v2) {
if (v2.substr(-2) == ".*") {
ip = Js5.namespace(v2.substring(0, v2.length - 2));
__imports__.push(ip);
args.push(ip);
} else {
args.push(Js5.importclass(v2));
}
});
} else if (Js5.isArray(v)) {
args = args.concat(v);
} else {
args.push(v);
}
});
return args;
}
function jextends() {
var oc = Object.prototype.constructor;
var l = arguments.length;
var sb = arguments[0];
var sp = arguments[1];
var mixins = [];
var coverrides;
if (l < 2) {
throw new Error("[jextends] invalid arguments");
}
if (l == 2) {
coverrides = sp;
sp = sb;
} else if (Js5.isArray(arguments[2])) {
mixins = arguments[2];
coverrides = sp;
sp = sb;
l = 2;
} else {
coverrides = arguments[2];
if (l == 4) {
mixins = arguments[3];
}
}
if (Js5.isString(sp)) {
sp = Js5.importclass(sp);
}
var E = function() {
},sbp,spp = sp.prototype;
E.prototype = spp;
mixins.unshift(spp);
if (Js5.isFunction(coverrides)) {
coverrides.$Define = true;
coverrides = coverrides.apply(this, mixins);
}
if (l == 2) {
sb = coverrides.constructor != oc ? coverrides.constructor : function() {
sp.apply(this, arguments);
};
}
sbp = sb.prototype = new E();
sbp.constructor = sb;
sb.superclass = spp;
if (spp.constructor == oc) {
spp.constructor = sp;
}
/*sbp.superclass = (function() {
return spp;
});*/
Js5.override(sb, coverrides); // extend coverrides
if (mixins.length > 1) {
for (var i = 1,len = mixins.length; i < len; i++) {
Js5.applyIf(sbp, mixins[i]);
}
}
return sb;
}
/**
* p1:String ==>class name
* p2,String ==>same package;Object
* p3,function ==>
*/
function jclass() {
var l = arguments.length,i = 0;
if (l == 0) {
throw new Error("[jclass] invalid arguments");
}
if (!Js5.isString(arguments[0])) {
throw new Error("[jclass] class name must be string");
}
if (l == 1) {
return jclass.caller && jclass.caller.$Define ? __cpackage__ && __cpackage__[name] ||
Js5.importclass(arguments[0]) : Js5.nameclass(arguments[0]);
}
var clf = arguments[l - 1];
var p;
if (l >= 3) {
var name = arguments[1];
if (Js5.isString(name)) {
p = __cpackage__ && __cpackage__[name] || Js5.importclass(name);
} else {
p = arguments[1];
}
} else {
p = Object;
}
if (!p) {
throw new Error("[jclass] unrecognized parent class");
}
var mixins = [];
if (l >= 4) {
var vs;
var mc;
Js5.each(Array.prototype.slice.call(arguments, 2, l - 1), function(v) {
if (Js5.isString(v)) {
vs = v.split(",");
Js5.each(vs, function(v2) {
mc = Js5.importclass(v2);
if (mc) {
mixins.push(mc.prototype);
}
});
} else {
mixins.push(v.prototype);
}
});
}
var cls = jextends(p, clf, mixins);
if (arguments[0]) {
__cpackage__[arguments[0]] = cls;
}
return cls;
}
function jnew() {
var l = arguments.length,i = 0;
if (l == 0) return {};
var args = Array.prototype.slice.call(arguments, 1);
var name = arguments[0];
var cls;
if (Js5.isString(name)) {
cls = jnew.caller && jnew.caller.$Define ?
__cpackage__ && __cpackage__[name]
|| Js5.importclass(name) : Js5.nameclass(name);
if (!cls) {
throw new Error("[jnew] unrecognized class,use whole class name");
}
} else {
cls = name;
}
/*var temp = function() {
};
var constructor = cls.prototype.constructor;
var instanceCls = function() {
return constructor.apply(this, args);
};
temp.prototype = cls.prototype;
instanceCls.prototype = new temp();
instanceCls.prototype.constructor = instanceCls;
return new instanceCls();*/
var obj = {};
Js5.override(obj, cls);
obj.__proto__ = cls.prototype;
cls.apply(obj, args);
return obj;
}
function jsupercall(cls, method, args) {
var sp = Js5.isString(cls) ? jsupercall.caller && jsupercall.caller.$Define ? Js5.importclass(cls) : Js5.nameclass(cls) : cls;
return sp.superclass[method].apply(this, args);
}
还有例子:
var jui = {};
jpackage("jui", function() {
jclass("Component", function() {
return {
constructor:function(x) {
console.log("Component:" + x);
},
show:function() {
console.log("Component");
}
}
});
jclass("Container", "Component", function(_supr) {
return {
constructor:function(x) {
console.log("Container:" + x);
_supr.constructor.call(this, x);
}
};
});
});
jpackage("jui", function() {
jclass("Window", "Container", function(_supr) {
return {
show:function() {
console.log("Window");
}
}
});
});
jpackage("jui.form", function() {
jimport("jui.*");
jclass("TextField", "Component", function(_supr) {
return {
show:function() {
console.log("TextField");
}
}
});
});
jpackage("js5.util", function() {
jclass("Observable", function(_supr) {
return {
constructor:function() {
console.log("Observable.constructor");
},
on:function() {
console.log("Observable.on");
},
show:function() {
console.log("Observable.show");
}
}
});
});
jpackage("jui.ex", jimport("jui.Window;jui.*;jui.form.*"), function(_W, j) {
jclass("Window", "jui.Window", "js5.util.Observable", function(_supr, _ob) {
return {
constructor:function(x) {
console.log("jui.ex.Window.constructor");
_supr.constructor.call(this, x);
_ob.constructor.call(this);
},
show:function() {
console.log("Window Ex");
_supr.show();
}
}
});
var MyWindow = jclass("", "jui.Window", function() {
return {
show:function() {
console.log("anonymous myWindow");
}
}
});
var x = jnew("Window", "package jui.ex.Window");
x.show();
x.on();
x = new MyWindow("ssssssss");
x.show();
jclass("jui.Window").superclass.constructor.call(this, "111111111111");
x = jnew(jui.Window, "jui.Window : new in package, use complete class path");
x.show();
x = new jui.Window("jui.Window : new in package, use complete class path");
x.show();
x = jnew("jui.Window", "jui.Window: new in package, use complete class path");
x.show();
x = new j["Window"]("jui.Window: new in package, use import jui.*");
x.show();
x = new _W("jui.Window: new in package, use import jui.Window");
x.show();
for (var i = 1; i <= 5; i++) {
x = jnew("TextField", "jui.form.TextField new in package,use import jui.form.*");
x.show();
}
});
var a = jextends(jui.Window, function() {
return {
show:function() {
console.log("jextends show");
}
}
});
var x = jnew("jui.ex.Window", "global jui.ex.Window");
x.show();
本文介绍了一个名为JS5的库,该库通过JavaScript实现了类似Java的关键特性,包括包管理、类继承、静态导入等。文章提供了详细的代码示例,展示了如何使用这些功能来组织和复用代码。
594

被折叠的 条评论
为什么被折叠?



