dom Framework oop模块
此模块提供强大的面向对象编程能力,非常感谢mootools等先行者做出的有益探索,虽然现在我放出来的版本比最初的削减了许多功能,但依然非常强大。
/*dom Framework version 1.0 Copyright 2010 Dual licensed under the MIT or GPL Version 2 licenses. author: <ruby> <rb>司徒正美<rp>(zhongqincheng)</rp></rb><rt>しとぅなさみ</rt></ruby> http://www.cnblogs.com/rubylouvre/ */ //========================================= // OOP模块 提供强大的面向对象编程, ruby风格的继承机制 //========================================== ;;;( function (dom,window,undefined){ dom.provide( "oop" ); var classMethods = ( function () { var include = [ "constructor" ], extend = 'prototype $supers $super extend include' .toArray(); function cleanModule(module, array) { array = array == 'extend' ? extend : include for ( var key in module){ if (module.hasOwnProperty(key) && array.contains(key)){ delete module[key] } } return module; } return { //桥梁模式,将实现化与抽象化脱耦,便得两者可以独立地变化 //http://javascript.crockford.com/prototypal.html inherit: function (parent) { if (parent && parent.prototype) { var bridge = function () {}; bridge.prototype = parent.prototype; this .prototype = new bridge; this .$ super = parent; } this .$supers = []; //这里的this为类 while (parent) { if (!dom.isPureObject(parent)){ //父类不能为默认添加的Object this .$supers.push(parent); parent = parent.$ super ; } } return this .prototype.constructor = this ; }, alias : function (oldName, newName){ var proto = this .prototype; if (dom.isString(oldName)){ var method = proto[oldName] method && (proto[newName] = method); } else if (is(oldName, "Object" )){ dom.each(oldName, function (neo,old){ this .alias(old,neo) }, this ) } return this ; }, //为新类添加一些类成员 extend: function () { dom.toArray(arguments).each( function (module){ dom.mixin( this , cleanModule(module, 'extend' )); }, this ); return this ; }, //为新类添加原型成员,如果它们是函数,则判断其与父类有没有同名方法, //有则改写当前类的成员,在它上面添加一个$super属性 include: function () { var $supers = this .$supers.pluck( 'prototype' ); dom.slice(arguments).each( function (module){ cleanModule(module, 'include' ); //去除模块包中那些危险属性 dom.keys(module).each( function (key){ var value = module[key],isFn = dom.is(value, "Function" ); if (key.startsWith( "protected " )){ key = key.toArray()[1]; if (isFn){ value._protected = true ; } } var parent = $supers.first( function (proto) { return dom.is(proto[key], "Function" ); }); this .prototype[key] = isFn ? ( function ( method, key, parent) { return function () { parent && ( this .$ super = parent[key]); if (method._protected && this ._method == null ){ throw new Error( 'The method "' + key + '" is protected!' ); } this ._method = arguments.callee; var result = method.apply( this , arguments); delete this ._method; return result; }; })(value, key, parent) :value; if (isFn){ this .prototype[key].toString = function (){ return String(value); } } }, this ); }, this ); return this ; } } })(); //第一类工厂 //{inherit :superclass,include:instance_member,extend:class_member,singleton:boolean} dom.oop = function (obj){ obj = obj || {}; //新类的原始构造器 var init = init || obj.init || dom.noop; delete obj.init; //父类 var superclass = obj.inherit || Object; //判定是否需要实现单例 var singleton = !!obj.singleton ; delete obj.singleton; //------------------创建新类-------------------------------------------- var klass = function () { if (singleton && klass.instance){ //实现单例模式 return klass.instance } superclass.apply( this , arguments); init.apply( this , arguments); if (singleton) klass.instance = this ; return this ; }; //添加泛化成员与原型成员 dom.mixin(klass, classMethods).inherit(superclass); [ "extend" , "include" ].each( function (name) { if (obj[name]) { var modules = dom.toArray(obj[name]); klass[name].apply(klass, modules); delete obj[name]; } }); var proto = klass.prototype; klass.include(obj); if (!proto.__proto__){ //修复IE与Opera中的第二条原型链 proto.__proto__ = proto } proto.$ super = superclass; klass.toString = function (){ //重写构造子的toString return init.toString(); } return klass } })(window[escape(document.URL.split( "#" )[0])], this ); |
一些示例:
继承。
var Animal = dom.oop({ init: function (name) { this .name = name; }, eat: function () { dom.console.log( 'yummie' ); } }); var Human = dom.oop({ inherit: Animal, //注意这里,使用inherit speak: function () { dom.console.log( this .name + ' said bla bla bla' ); } }); var peter = new Human( 'peter' ); peter.eat(); //yummie peter.speak(); //peter said bla bla bla var Pat = dom.oop({ inherit: Human, //注意这里,使用inherit init: function (name,age) { //注意这里name this .age = age //隐式调用父类构造子 } }); var pat = new Pat( 'pat' ,18); dom.console.log(pat.name) //pat dom.console.log(pat.age) //18 pat.speak(); //pat said bla bla bla |
单例类。
var God = dom.oop({ init: function (name){ this .name = name; this .alertName = function (){ dom.console.log( this .name) } }, singleton: true //注意这里,使用singleton属性 }); var god = new God( "耶和华" ); god.alertName(); //alerts 耶和华 var lucifer = new God( "撒旦" ); lucifer.alertName(); //alerts 耶和华 dom.console.log(god === lucifer ) //alerts true |
内部方法,只能用于类的内部与其子类。注意,是方法不是属性。
var Person = dom.oop({ init: function (name){ this .name = name; }, "protected secret" : function (){ //定义一个内部方法,要用"protected "作为前缀 return 'I sometimes like girly drinks' ; }, describe: function (){ return "Hi, I'm #{name}. #{secret}. I kid, I kid." .instead({ name: this .name, secret: this .secret() }); } }); var scott = new Person('司徒正美 '); try{ scott.secret() }catch(e){ dom.console.error(e);//Error: The method "secret" is protected! } dom.console.log(scott.describe());//Hi, I' m Scott. I sometimes like girly drinks. I kid, I kid. |
更多见文档!
下载回来后对着文件点右键-->属性-->解除锁定。
如果大家对上述方法有什么更好的实现,请不吝赐救!
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?