之前的写过一篇关于js类的《文章》,主要是贴了一下代码和用法,功能上也有些欠缺。新版的Class增加了私有属性、接口两个功能。需要注意的是继承、调用父类方法、使用私有方法都是很耗费资源的,如果非得使用尽量减少继承的层数。(本人的小demo)
主要贴一下私有属性和接口用法:
1、私有属性
//设置私有属性this.$(key,value);获取私有属性:this.$(key); Class('Dog',{ initialize:function(){ //为Dog设置私有属性name this.$('name','dog'); }, speak:function(){ //打印Dog私有属性name console.log('Dog name is ',this.$('name')); } }) Class('BlackDog',{ superclass:Dog, initialize:function(){ this.callSuper(); //为BlackDog也设置私有属性name,检查子类和父类里的私有属性是否冲突 this.$('name','blackdog'); }, speak:function(){ this.callSuper(); //打印BlackDog私有属性name console.log('BlackDog name is ',this.$('name')); } }) //正确结果应该Dog里的name和BlackDog里的name没有关系,BlackDog不能覆盖Dog里的私有属性 var blackdog=new BlackDog(); blackdog.speak();
结果为:
Dog name is dog BlackDog name is blackdog
2、接口
Interface('Animal',['eat']);//接口名称、方法 Class('Pig',{ interfaces:[Animal] }) Interface('Animal',['eat']);//接口名称、方法 Class('Cat',{ interfaces:[Animal], eat:function(){ } })
结果为:
报错:Error: the method 'eat' need to implement in class 'Pig'!
下边是新版的源码:
(function () { var emptyArgs = [], emptyFn = function () { }, //暂时未用 noInvokeResult = { execute: emptyFn }, //暂时未用 invokeSuperResult = { execute: function () { var result = this.method.apply(this.obj, arguments || emptyArgs); this.obj = null; this.method = null; return result; } }, //暂时未用 enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor']; //命名空间 function namespace() { // namespace var a = arguments, al = a.length, o = null, i, j, d, dl, rt; for (i = 0; i < al; ++i) { d = a[i].split("."); rt = d[0]; eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';'); dl = d.length; for (j = 1; j < dl; ++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 bindMethods(object, methods) { for (var name in methods) { if (methods.hasOwnProperty(name)) { object[name] = methods[name]; } } } //添加方法到原型 function addMethods(C, methods) { var p = C.prototype, _methods_ = C._methods_; for (var name in methods) { var m = methods[name]; p[name] = m; if (name != 'callSuper' && name != 'invokeSuper') { m['_name_'] = name; m['_owner_'] = C; if (_methods_.indexOf(name) == -1) { _methods_.push(name); } } } 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._wrapper_) { superMethod = method._wrapper_.superclass; } else { superMethod = emptyFn; } return superMethod.apply(this, arguments || emptyArgs); } } //暂时未用 var staticUtil = { getStatic: function (name) { return this.constructor[name]; } }; //使用方法名调用父类方法 var invokeSuper = (function () { var obj, superMethod, proxyResult = { execute: function () { var result = superMethod.apply(obj, arguments || emptyArgs); 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 createPrivateClosure() { var privateProperties = {}; return function (key, value) { if (value == undefined) { return privateProperties[key]; } else { privateProperties[key] = value; } } } ////////////////////////////////////////////////////////////Class/////////////////////////////////////////////////////////// //创建类 function Class() { var clazz, options, initialize, interfaces, 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 (options.hasOwnProperty('initialize')) { initialize = options['initialize']; delete options['initialize']; } else { initialize = function () { }; } statics = options.hasOwnProperty('statics') ? options['statics'] : false; clazz = function () { var self = this, //私有属性的赋值、取值方法 $ = function (key, value) { var $method = arguments.callee, caller = $method.caller, callerClass = caller._owner_ || caller._wrapper_; if (callerClass == $method._owner_) { return $method.$$(key, value); } else { $method = $method._super_; while ($method) { if (callerClass == $method._owner_) { break; } $method = $method._super_; } } return $method.$$(key, value); }; $.$$ = createPrivateClosure(); $._owner_ = clazz; if (self.$) { $._super_ = self.$; } self.$ = $; //增加静态方法到实例本身 statics && bindMethods(self, statics); initialize.apply(self, arguments); }; initialize._wrapper_ = clazz; clazz._isClass_ = true; clazz._name_ = className; clazz._fullName_ = fullName; clazz._methods_ = []; clazz._interfaces_ = []; interfaces = options['interfaces']; mixin = options['mixin']; delete options['interfaces']; delete options['mixin']; //增加静态方法到类 if (statics) {//TODO 火狐中name属性无法赋值 for (var k in statics) { if (statics.hasOwnProperty(k)) { clazz[k] = statics[k]; } } delete options['statics']; addMethods(clazz, staticUtil); } //继承父类 if (options.hasOwnProperty('superclass')) { superclass = options['superclass']; if (superclass) { inherit(clazz, superclass); superclass.prototype.callSuper || addMethods(clazz, { callSuper: callSuper, invokeSuper: invokeSuper }); delete options['superclass']; } else { throw TypeError("the superclass of '" + fullName + "' is undefined!"); } } //添加公有方法到类 addMethods(clazz, options); //添加mixin方法到类 if (mixin) { if (mixin.length && mixin.pop) { for (var i = 0; mixin[i] != undefined; i++) { addMethods(clazz, mixin[i]); } } else { addMethods(clazz, mixin); } delete options['mixin']; } //实现、检查接口 if (interfaces) { var _interfaces_ = clazz._interfaces_, _methods_ = clazz._methods_; if (!(interfaces instanceof Array)) { interfaces = [interfaces]; } for (var i = 0, inter, methodName; interfaces[i] != undefined; i++) { inter = interfaces[i]; for (var j = 0; inter[j] != undefined; j++) { methodName = inter[j]; if (_methods_.indexOf(methodName) == -1) { throw new Error("the method '" + methodName + "' need to implement in class '" + fullName + "'!"); } } _interfaces_.push(inter); } } if (className) { path[className] = clazz; path = arguments[0]; } return clazz; } window.Class = Class; //命名空间 Class.ns = namespace; //根据路径获取类 Class.get = function (source) { try { var path = source.split('.'), obj = window[path[0]]; if (path.length > 1) { for (var i = 1; path[i] != undefined; i++) { obj = obj[path[i]]; } } return obj; } catch (e) { throw new TypeError("no such class '" + source + "' is defined!"); } }; //为类设置别名 Class.alias = function (source, alias) { var clazz, path = alias.split('.'), aliasName = path.pop(), aliasPath = path.join('.'); if (typeof source == 'string') { clazz = Class.get(source); } else if (source._isClass_) { clazz = source; } if (clazz) { if (aliasPath) { namespace(aliasPath); Class.get(aliasPath)[aliasName] = clazz; } else { window[aliasName] = clazz; } } }; ////////////////////////////////////////////////////////////Interface/////////////////////////////////////////////////////////// function _interface(fullName, methods) { this.fullName = fullName; for (var i = 0; methods[i] != undefined; i++) { this[i] = methods[i] } } function Interface(fullName, methods) { if (methods instanceof Array) { var path = fullName.split("."), className = path.pop(); if (path.length > 0) { path = namespace(path.join('.')); } else { path = window; } path[className] = new _interface(fullName, methods); } else { throw new Error("Interface '" + fullName + "' second must be Array!"); } } window.Interface = Interface; })();
代码还需改进,努力中
相关推荐
这东西在Javascript里用得会非常的频繁,因为针对现在的网页,多个基于同一个类对象的页面不多,往往不同块对象的交互就可以解决问题了,这就需要在JS针对元素定义几个静态类就可以完事了,进入正题。
7.js.cs 常用js代码 8.文件操作类 9.数据检查类 10.util.cs常用字符串操作 11.CacheManager.cs 操作缓存的类 12.CookieManager.cs Cookie管理类 13.DataToExcel.cs 导出excel 14.EnumConvert 枚举转换为详细说明的类...
JsHelper--Javascript操作帮助类,输出各种JS方法,方便不懂JS的人使用,减少代码量 7.JSON 转化类 ConvertJson List转成Json|对象转成Json|集合转成Json|DataSet转成Json|DataTable转成Json|DataReader转成Json...
继续上一篇文章《如何编写高质量JS代码》今次整理一下javascript函数知识点。 2.使用函数 函数给程序员提供了主要的抽象功能,又提供实现机制。函数可以独立实现其他语言中的多个不同的特性,例如,过程、方法、构造...
uploader 大文件、断点续传、分片、秒传、普通文件上传样例工具类包封装了一些关于分片md5验证、断点续传、分片上传、等方法前端样例使用百度插件 WebUploader , 插件的源码还是有一定的问题的样例包对插件源码做了...
4.图片上传部分:在文件上传部分已有功能的基础上实现了上传前缩略图预览,前台js文件后缀验证,后台代码文件后缀验证和文件类型验证(就算修改后缀名也无法成功上传),支持图片上传前压缩; 5.多选择器多文件上传...
利用webuploader实现bs端的断点续传,利用webuploader的多线程分片上传机制,利用分片md5校验断点。请直接查看jsp和java类,无视架构问题,需要下载webuploader的js和css,jar包自行下载
学习笔记,方便以后查阅。解决上一篇留下的问题。拖拽图钉,弹出交互信息窗口。读取和使用交互窗口中的控件。
JsHelper--Javascript操作帮助类,输出各种JS方法,方便不懂JS的人使用,减少代码量 7.JSON 转化类 ConvertJson List转成Json|对象转成Json|集合转成Json|DataSet转成Json|DataTable转成Json|DataReader转成Json...
Humans_Emotions_Codes- 函数,对象和类(续... 2)和“继承”
比之前的合集更丰富详细的细节;没有最新只有更新! 1、建立GPRS连接 4 2、判断网络状态是否可用 4 3、获得惯性滑动的位置 5 ...103、JS 148 104、TextView多行末尾显示省略号 148 105、竖直显示的textView 153
fastdfs基于http协议的分布式文件系统源码,基于go和js,它具有高性能、高可靠、无中心、免维护等优点。 ### 大家担心的是这么简单的文件系统,靠不靠谱,可不可以用于生产环境?答案是肯定的,正因为简单所以高效...
2,解决了地区运费单独设定续重时,运费计算错误问题 3,后台首页增加了退款申请的展示 4,优化了城市js联动 5,修复了收藏夹弹出bug 6,修复了团购,抢购等js错误和计时错误问题 7,修复了退款申请拒绝时弹出退款...
完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则表达式 delegate vs. event 我是谁?[C#] 表达式计算引擎 正式发布表达式计算引擎WfcExp V0.9(附源码) 运算...
支持c/c++, h,hpp,cxx,js,java,php等类C语言的注释清理,支持自定义后缀名 2。支持utf8,ansi,gb2312,gb18030,gbk, and gbxx 3。支持xp, win7及以上32/64 windows系统 4。支持行注释//.... 5。支持续行注释//....\ 6...
lib/server.js端点列表和实际的服务器启动lib/cron.js后台任务和运行它们的包装器lib/permission-manager.js一个用于计算权限相关内容的类我如何... ...运行测试? 只需在本地文件夹中运行npm test 。 不要忘记运行...
类簇的优缺点; App启动的完整过程; SDWebImage原理; 三次握⼿与四次挥⼿; 怎么防⽌反编译; CTMediator⽅案; Block⼀定会造成强引⽤吗; 断点续传; JS原理; 组件化过程; 分类的底层实现; 监控、优化 APP...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...
该实例可进行局域网的聊天、一对多、多对一、和多对多的传送和续传,理论上这是我本人的实现目的,而且目前经测试已基本实现了上述功能,而且网速一般有几M/S。另外有只打开一个应用程序、CRichEdit的使用、最小到...