读书人

发个JS练手作品简单的OO封装解决思路

发布时间: 2012-05-03 14:06:56 作者: rapoo

发个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还在入门中,表示看不懂这些
[解决办法]
这。。。。好深奥啊,新手表示看不懂
[解决办法]
楼主应该写点注释
[解决办法]
谢谢分享。。。。。。。。。。。。。
[解决办法]
探讨

引用:
楼看过mootool源码吧。

以前粗粗的看了下prototype的源码,那个klass就参考了prototype中的实现。
刚开始的时候感觉它的那个构造函数太长想该的短一点,后来就慢慢的改成了
现在这个样子。

[解决办法]

[解决办法]
太高深了
[解决办法]
哎。看不懂呐。




--------------------------------------帅签分割线-------------------------------------------------

[解决办法]
学习了。
[解决办法]
这么写主要是为了解决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

留备以后学习
[解决办法]
看不太懂,但是还是认真看完了,
[解决办法]
厉害啊!不错的

读书人网 >JavaScript

热点推荐