发个JS练手作品,简单的OO封装
最近翻书复习了下基础知识,感觉书上的面向对象的例子用起来不是很顺手
所以自己改了下,纯粹练手,有意见的请拍砖,当然最好能给出更好的例子。
- JScript code
var $class = (function(){ var guid = 0, classMap = {}, caller = null, callStack = []; return { create : createClass } //------------------------[辅助函数部分]------------------------ /** * 创建新类. * @param {constructor}superClass 超类构造器,该类必须由$class.create创建 * @param {Json}proto 类原型 * @return {constructor} */ function createClass(superClass, proto){ var isSuperValid = superClass instanceof Function && superClass.prototype && superClass.prototype.init instanceof Function; superClass = isSuperValid ? superClass : null; var superProto = superClass ? superClass.prototype : null; //定义类构造函数 var klass = function() { var args = [].slice.call(arguments); //执行父类构造函数. if(superClass){ superClass.apply(this, args); } //若自己的原型中有init方法,执行init if(klass.prototype.hasOwnProperty('init')){ klass.prototype.init.apply(this, args); } }; //定义类原型 var klassProto = getClassProto(superProto, proto); klassProto.constructor = klass; klass.prototype = klassProto; //返回类 return klass; } /** * 获取类原型. * @param {json}superProto 超类原型 * @param {Json}overwrites 需要重写方法 * @return {json} */ function getClassProto(superProto, overwrites) { var i, F, proto, classId = getGuid(); if(superProto){ F = function(){}; F.prototype = superProto; proto = new F(); }else{ proto = getDefaultProto(); } //用overwrites中方法覆盖原型中的方法 for(i in overwrites){ if(overwrites.hasOwnProperty(i)){ proto[i] = overwrites[i]; } } //修复IE中for in不能遍历toString、valueOf等属性的Bug if(document.all){ var len, method, methods = ['toString', 'valueOf']; for(i=0, len = methods.length; i < len; i++){ method = methods[i]; if( overwrites.hasOwnProperty(method) ){ proto[method] = overwrites[method]; } } } //注册类关系 proto.classId = classId; regClass(proto, superProto); //确保原型中含有必要的原型方法 addMastHasMethods(proto); return proto; } /** * 获取默认原型. * @return {json} */ function getDefaultProto(){ return { init : function(){}, callSuper : callSuper }; } /** * 调用超类方法. * @param {String}methodName 方法名 * @return */ function callSuper(methodName){ caller = (caller === null ? this : caller); var curClsId = callStack.length > 0 ? callStack[callStack.length - 1] : this.classId; var args = [].slice.call(arguments, 1), parent = getParent(curClsId), ret; if(parent && parent[methodName]){ callStack.push(parent.classId); try{ ret = parent[methodName].apply(caller, args); }catch(e){ alert(e); } callStack.pop(); } //调用完毕后将调用上下文清空 if(callStack.length === 0){ caller = null; } return ret; } /** * 将类信息注册到类记录表中. * @param {json}proto 类原型. * @param {json}parent 超类原型 */ function regClass(proto, superProto){ var classId = proto.classId; classMap[classId] = { id : classId, proto : proto, parent: superProto }; } /** * 检查原型链中是否有必须要实现的方法,没有的话,向原型中添加. * @param {json}proto */ function addMastHasMethods(proto){ var i, dftProto = getDefaultProto(); for(i in dftProto){ if(dftProto.hasOwnProperty(i) && !proto[i]){ proto[i] = dftProto[i]; } } } /** * 获取guid. * @return {int} */ function getGuid(){ return guid++; } /** * 获取超类原型. * @param {int}classId 类ID * @return {json} 超类原型, 若存在返回null. */ function getParent(classId){ var record = classMap[classId]; return record ? record.parent : null; }})();var Man = $class.create(null, { init : function(cfg){ this.name = cfg.name; this.age = cfg.age; }, say : function(){ alert('my name is:' + this.name + ", " + this.age); }, toString : function(){ return ( 'name: ' + this.name + ', age: ' + this.age ); }});var Student = $class.create(Man, { init : function(cfg){ //执行此方法前会自动调用Man.init this.stuNum = cfg.stuNum; }, say : function(){ this.callSuper('say'); //调用父类方法 alert("i'm a student, my student number is " + this.stuNum); }, toString : function(){ return ( this.callSuper('toString') + ', stuNum: ' + this.stuNum ); }});window.onload = function(){ var m1 = new Man({name : '张三', age: 20}), s1 = new Student({ name : '王五', age : 22, stuNum : 'no-1' }); m1.say(); s1.say(); alert(m1.toString() + "\n" + s1.toString());};
[解决办法]
学习了!
[解决办法]
[解决办法]
楼主好人,copy学习下
[解决办法]
[解决办法]
$class.create(null, {
init : function(cfg){
this.name = cfg.name;
this.age = cfg.age;
}
建议把这个null省略掉
[解决办法]
一直不怎么喜欢以OO方式写JS,不过大势所趋,代码多了也确实OO会方便些
收藏以备深入学习
[解决办法]
喜欢OO也喜欢XX
[解决办法]
楼主算法的目的是什么?
[解决办法]
算法核心部分应该就是继承的功能,LZ应该是出于这个目的
尽可能的向OO靠齐
[解决办法]
支持,这么写一边自己对OO又加深了印象
[解决办法]
楼看过mootool源码吧。
[解决办法]
要需要在重写的方法中引用
父类的方法。
[解决办法]
姑且不说别的 代码写的很规整 境界很高深 我无比敬佩 这才是一个优秀的coding开发人员 我顶你~~~
[解决办法]
楼主强大,咱JS还在入门中,表示看不懂这些
[解决办法]
这。。。。好深奥啊,新手表示看不懂
[解决办法]
楼主应该写点注释
[解决办法]
谢谢分享。。。。。。。。。。。。。
[解决办法]
[解决办法]
[解决办法]
太高深了
[解决办法]
哎。看不懂呐。
--------------------------------------帅签分割线-------------------------------------------------
[解决办法]
学习了。
[解决办法]
这么写主要是为了解决JS继承中一个很麻烦的问题:
你既要重写父类的方法,要需要在重写的方法中引用
父类的方法。
===========================
function merge(a, b) //ensure a and b are both 'function' type
{
if(a && a != b)
{
var merged = function(){
this.__super__ = arguments.callee.__super__;
return b.apply(this, arguments);
}
merged.__super__ = a;
return merged;
}
return a;
}
在getClassProto中的循环检查同名函数然后merge。
在实例中可以直接在各个方法内直接this.__super__(1,2,3);
省去callStack另外init也能__super__
如say : function(str)
{
this.__super__();
alert('say:' + str);
}
[解决办法]
mark
------解决方案--------------------
学习一下
[解决办法]
楼主看的什么书啊?
[解决办法]
楼主写点注释啊,要不新手看不懂。
[解决办法]
厉害。oo确实使用很方便。
oo 再加上VS2010,那真是完美了
-----------------------------
新版老虎插件即将登场:
[解决办法]
牛人呀·····
[解决办法]
[解决办法]
不知道js面向对象是不是真的大势所趋
[解决办法]
看不懂啊看不懂。。。
[解决办法]
- JScript code
(function(){var Base = window.Base = Base || { ///summary: 静态方法,创建抽象类 create: function () { return function () { this.initialize.apply(this, arguments); } }, ///summary: 静态方法,实现继承,允许重载 extend: function () { if (1 == arguments.length) { for (var p in arguments[0]) this[p] = arguments[0][p]; return this; }; for (var p in arguments[1]) arguments[0][p] = arguments[1][p]; return arguments[0]; }, ///summary: Cookie类 Cookie: function () { var Cookie = Base.create(); Cookie.prototype = { initialize: function () { }, ///写cookie setCookie: function (name, value) { var date = new Date(); date.setTime(date.getTime() + 30 * 24 * 3066 * 1000); document.cookie = name + "=" + value + ";expires=" + date.toGMTString() }, ///读cookie getCookie: function (name) { var CookieArray = document.cookie.split(";"); for (var i = 0; i < CookieArray.length; i++) { var arr = CookieArray[i].split("="); if (arr[0] == name) { return arr[1]; break; } } }, ///清除cookie clearCookie: function (name) { document.cookie = name + "=''; expires=Thu, 01-Jan-70 00:00:01 GMT"; } } return new Cookie(); } };})();
[解决办法]
楼主强大
[解决办法]
学习了
[解决办法]
留下脚印,copy
[解决办法]
向老鸟看齐,顶楼主
[解决办法]
mark & up
留备以后学习
[解决办法]
看不太懂,但是还是认真看完了,
[解决办法]
厉害啊!不错的