js类有很多中写法,网上也有很多现成的库,都有各自的优缺点,但用起来都不太顺手。所以总结改进后,写了自己的类,只图用起来顺手,看起来顺眼。
比较喜欢mootools,语法和它类似。initialize为构造方法,statics为静态属性及方法,superclass为父类;在当前方法中调用父类方法使用this.callSuper(),在当前方法中调用父类的其它方法this.invokeSuper('methodName').execute(args);
js中类的写法有一个痛点,即没法完全实现私有属性方法、受保护属性方法。mootools中有相关的内容,但也只是在继承的层面上实现部分功能,并不能控制一个对象外部对私有方法、受保护方法的访问。
使用方法如下:
Class('myclass.A',{ initialize:function(){ this.name='A'; }, showName:function(){ alert(this.name); } }); Class('myclass.B',{ superclass:myclass.A, initialize:function(){ this.name='B'; }, showSuperName:function(){ this.invokeSuper('showName').execute(); }, showName:function(){ alert('<<<') this.callSuper(); alert('>>>') } }); var a=new myclass.A(); a.showName(); var b=new myclass.B(); b.showName(); var b=new myclass.B(); b.showSuperName();
源码如下,仍需完善,仅供大家参考。
(function () { var noArgs = [], emptyFn = function () { }, noInvokeResult = { execute: emptyFn }, invokeSuperResult = { execute: function () { var result = this.method.apply(this.obj, arguments || noArgs); this.obj = null; this.method = null; return result; } }, enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor']; function namespace() { // namespace var a = arguments, o = null, i, j, d, rt; for (i = 0; i < a.length; ++i) { d = a[i].split("."); rt = d[0]; eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';'); for (j = 1; j < d.length; ++j) { o[d[j]] = o[d[j]] || {}; o = o[d[j]]; } } return o; } function inherit(C, superClass) { if (typeof(superClass) != 'function') { return C; } function F() {} F.prototype = superClass.prototype; C.prototype = new F(); C.prototype.constructor = C; C.superclass = superClass; return C; } function addMethods(C, methods) { var p = C.prototype; for (var name in methods) { var m = methods[name]; m['_name_'] = name; m['_owner_'] = C; p[name] = m; } return C; } //TODO 1、需增加获取静态属性、方法的方法2、增加获取祖先的方法ancestor function callSuper() { var method = arguments.callee.caller, superMethod; if (method) { if (method._owner_) { superMethod = method._owner_.superclass.prototype[method._name_]; } else if (method.superclass) { superMethod = method.superclass; } else { superMethod = emptyFn; } return superMethod.apply(this, arguments || noArgs); } } var staticUtil = { getStatic: function (name) { return this.constructor[name]; } }; var invokeSuper = (function () { var obj, superMethod, proxyResult = { execute: function () { var result = superMethod.apply(obj, arguments || noArgs); obj = null; superMethod = null; return result; } }; function proxy(name) { try { superMethod = proxy.caller._owner_.superclass.prototype[name]; if (!superMethod) { throw(0); } obj = this; return proxyResult; } catch (e) { throw(new Error("[invokeSuper error]: the method " + name + "'s super is not exist!")); } } return proxy; })(); function Class() { var options, initialize, superclass, statics, mixin, fullName, className, path; if (arguments.length == 1) { options = arguments[0]; } else if (arguments.length == 2) { fullName = arguments[0]; path = fullName.split("."); className = path.pop(); if (path.length > 0) { path = namespace(path.join('.')); } else { path = window; } options = arguments[1]; } else { fullName = ""; className = ""; } if ('initialize' in options) { initialize = options['initialize']; delete options['initialize']; } else { initialize = function () { }; } // TODO火狐中name属性无法赋值 if (options.hasOwnProperty('statics')) { statics = options['statics']; for (var k in statics) { if (statics.hasOwnProperty(k)) { initialize[k] = statics[k]; } } delete options['statics']; addMethods(initialize, staticUtil); } if ('superclass' in options) { superclass = options['superclass']; if (superclass) { inherit(initialize, superclass); superclass.prototype.callSuper || addMethods(initialize, { callSuper: callSuper, invokeSuper: invokeSuper }); delete options['superclass']; } else { throw TypeError("the superclass of '" + fullName + "' is undefined!"); } } addMethods(initialize, options); if (options.hasOwnProperty('mixin')) { mixin = options['mixin']; if(mixin.length&&mixin.pop){ for(var i=0;mixin[i]!=undefined;i++){ addMethods(initialize,mixin[i]); } }else{ addMethods(initialize,mixin); } delete options['mixin']; } if (className) { path[className] = initialize; path = arguments[0]; } initialize._isClass_ = true; initialize._name_ = className; initialize._fullName_ = fullName; return initialize; } window.Class = Class; })();
相关推荐
JavaScript中的MD5加密工具类是用于对数据进行安全哈希的一种方法,广泛应用于密码存储、数据完整性校验等场景。MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,它能将任意长度的输入转化为固定长度的...
类定义了一类事物公共的行为和方法;而实例则是类的一个具体实现。 我们还知道,面向对象编程有三个重要的概念 - 封装、继承和多态。 但是在JavaScript的世界中,所有的这一切特性似乎都不存在。 因为JavaScript...
JavaScript(JS)是一种广泛应用于客户端和服务器端的脚本语言,尤其在Web开发中占据着重要地位。其语法简洁,学习曲线相对平缓,使得它成为开发者的首选工具之一。 "javascript.cs" 这个文件名暗示了这是一个用C#...
在本案例中,"可封装为JS类"意味着开发者创建了一个可复用的JavaScript对象,该对象可以方便地管理和控制这些弹出窗口。 首先,让我们了解`div`元素。在HTML中,`<div>`是“division”(分隔)的缩写,是一个通用的...
2. **类与实例**:在JavaScript中,类的概念相对较弱,但Prototype.js引入了`Class.create`函数,允许我们创建类的实例,模拟传统的面向对象编程中的类。 3. **函数委托**:Prototype.js通过`Prototype.Browser`来...
C#的一个JS类C#的一个JS类C#的一个JS类C#的一个JS类C#的一个JS类C#的一个JS类C#的一个JS类
尽管没有具体的代码,但可以想象它可能包含了一个使用上述类方式实现的JavaScript类。通过分析这个文件,我们可以学习到实际编程中类的运用,以及如何将理论知识应用到实践中。 总结起来,JavaScript的类方式多种...
"自定义JS类框架"指的是开发者根据自身需求,利用JavaScript语言特性(如原型链、闭包、模块化等)和jQuery库,构建的一种自定义的框架。这个框架可能是为了简化DOM操作、提供更高级别的API、优化性能或者实现特定的...
在这个场景下,"通用不间断滚动JS封装类"可能是一个自定义的JavaScript类,它包含了实现滚动效果所需的所有方法和属性。 描述中提到的博文链接(https://aina5626.iteye.com/blog/1201724)是深入理解这个封装类的...
在文件名“Asp.net好用的JS脚步类”中,我们可以推测这可能是一个包含实用JavaScript函数或类的集合,这些函数或类可能是为了解决ASP.NET开发中常见问题而设计的,比如表单验证、数据格式化、用户界面交互等。...
通过这样的通用JavaScript类,开发者可以创建出更健壮、可维护的ASP.NET应用,同时提高开发效率。不过,随着技术的发展,现代Web开发中更多地倾向于使用库和框架(如jQuery、React、Vue等),它们提供了更高级别的...
基于jquery的form表单验证类,工程项目为.net项目,主要是做了详细的调用例子,如果不使用.net,可以直接formvaildator-1.0.js或formvaildator-1.0.min.js,里面也有详细的调用说明,不过项目说明因为有例子会直观...
在JavaScript编程中,封装是面向对象编程的一个重要概念,它有助于提高代码的可...在压缩包文件“常用的js类”中,可能包含了这些功能的具体实现,新手可以通过学习和理解这些代码,进一步提升自己的JavaScript技能。
根据提供的文件信息,我们可以看到这是一个用于封装JavaScript功能的C#类。下面将详细介绍该类中的各个方法及其用途。 ### 封装JS工具类 #### 1. Echo 方法 该方法的功能是向客户端输出指定的消息。 ```csharp ...
标题中的“省、市、地区联动选择JS封装类”指的是一个JavaScript编程实现的功能,它用于在网页中创建一个联动选择的下拉菜单,通常用于用户输入他们的省份、城市和区域信息。这种联动选择框能够根据用户选择的省份...
在IT行业中,编程语言JavaScript(js)是一种广泛使用的脚本语言,尤其在Web开发领域,无论是前端还是后端都有其身影。在这个场景中,我们关注的是一个名为"公历与农历互转的js类"的工具,它适用于微信小程序以及H5...
本文将深入探讨JavaScript中的类和继承,并结合`prototype.js`文件中的示例进行解析。 ### 类的概念与模拟 在JavaScript中,我们通常使用函数来模拟类的行为。一个函数可以看作是一个类的定义,通过`new`关键字来...
在提供的`ClassDefineAndExtends.js`文件中,可能包含了关于类定义和继承的示例代码。通过分析这个文件,我们可以看到实际应用中的类定义和继承实践,包括如何定义类,如何使用构造函数初始化对象,以及如何通过`...
此程序是javascript和php开发,提供酒店、门票订购... 此程序中js是驴妈妈上的,我做了些修改,做学习用,精简了代码和功能,只提供酒店和门票,部分提交url请自己修改。php生成日历的类是自己原创的。不足之处请反馈。