• 技术文章 >web前端 >js教程

    Javascript面向对象扩展库代码分享_js面向对象

    2016-05-16 17:54:48原创495
    lang.js库提供了包和类的定义、类的继承与混合(mixin)、函数重载等功能,基本可满足大多数面向对象设计的需求。同时支持基于链式的定义方式,让库在使用时更加规范和便捷。下面首先通过简单的例子演示了lang.js的基本功能,之后给出了lang.js的源码及注释。
    一.功能介绍
    “lang”作为框架的全局定义,其中包括了四个方法:
    lang.Package(string name) //用于定义包(默认会暴露到全局)
    lang.Class(string name[, object config], object classBody) //用于定义类
    lang.Object(string name | object body) //用于定义支持重载函数的普通对象
    lang.Function(string name | object body) //用于定义重载函数
    复制代码 代码如下:

    var lang = (function(){
    /***********************************
    Javascript面向对象扩展库(lang.js v1.0)
    By: X!ao_f
    QQ: 120000512
    Mail: xiao_f.mail#163.com
    ************************************/
    var customToString = function(){
    return '[' + this.Type.type + ' ' + this.Type.name + ']';
    }
    //支持重载的方法定义
    var createMethod = (function(){
    //创建一个代理函数
    var createMethodProxy = function(context, name){
    //当调用重载的函数时,首先会执行该函数分析传入的参数,进行匹配和转发
    var method = function(){
    //在第一次调用时初始化,将映射信息缓存
    if(!method.__initialized__){
    initializeMethod(method);
    }
    //将参数类型拼接成函数签名
    var signature;
    if(arguments.length){
    var list = [];
    for(var i=0; ivar typename;
    var argument = arguments[i];
    if(argument === undefined || argument === null){
    typename = 'object';
    }else if(argument instanceof Array){
    typename = 'array';
    }else if(argument instanceof Date){
    typename = 'date';
    }else{
    typename = typeof argument;
    if(typename == 'object'){
    if('Class' in argument){
    typename = argument.Class.Type.name;
    }else if('nodeType' in argument){
    typename = 'element';
    }
    }
    }
    list.push(typename);
    }
    signature = list.join(',');
    }else{
    signature = '';
    }
    //如果常规缓存中存在匹配的签名,直接调用
    if(method.__overloads__[signature]){
    return method.__overloads__[signature].apply(this, arguments);
    }else{
    //缓存中不存在时,尝试利用正则进行模糊匹配
    //首先判断模糊匹配缓存中是否存在记录,如存在直接调用
    if(method.__overloadsCache__[signature]){
    return method.__overloadsCache__[signature].apply(this, arguments);
    }
    //循环匹配
    for(var i=0; i//如果匹配成功,将映射关系存入模糊匹配缓存,同时调用并返回
    if(method.__overloadsRegExp__[i].regexp.test(signature)){
    method.__overloadsCache__[signature] = method.__overloadsRegExp__[i].fn;
    return method.__overloadsRegExp__[i].fn.apply(this, arguments);
    }
    }
    //如果依然无法找到对应的函数,判断是否存在默认函数
    if(method.__overloads__['default']){
    return method.__overloads__['default'].apply(this, arguments);
    }else if(method.__overloads__['']){
    return method.__overloads__[''].apply(this, arguments);
    }else{
    alert('Error: '+method.Type.name+'('+signature+') is undefined.');
    }
    }
    };
    //内置对象
    method.__context__ = context;
    method.__functions__ = {};
    method.toString = customToString;
    //自描述信息
    method.Type = {
    name: name,
    Method: method,
    type: 'method'
    };
    return method;
    }
    //初始化
    var initializeMethod = function(method){
    //基础签名缓存
    method.__overloads__ = {};
    //模糊匹配正则缓存
    method.__overloadsRegExp__ = [];
    //模糊匹配结果缓存
    method.__overloadsCache__ = {};
    //例举所有定义的函数
    for(var signature in method.__functions__){
    var fn = method.__functions__[signature];
    var params = signature.substring(signature.indexOf('(') + 1, signature.length - 1);
    var pure = !/[\*\+\?\{]/.test(params);
    //如果不存在通配符直接保存到基础签名缓存
    if(pure){
    method.__overloads__[params] = fn;
    }else{
    //生成模糊匹配正则
    var regexp = '^' + params
    .replace(/([\w\.]+)(\{.*?\})?/g, '($1(,|$))$2')
    .replace(/\./g, '\\.')
    .replace(/((\()var(\())/g, '$2\\w+$3')
    .replace(/,\(/g, '(') + '$';
    method.__overloadsRegExp__.push({ regexp: new RegExp(regexp), fn: fn });
    }
    }
    method.__initialized__ = true;
    }
    //返回外部的定义函数
    return function(signature, fn, comp){
    //如果传入的为一个对象,视为定义匿名方法
    if(typeof signature == 'object'){
    var context = {};
    var method;
    for(var key in signature){
    method = createMethod.call(context, 'anonymous'+key, signature[key]);
    }
    return method;
    }
    signature = signature.replace(/\s+/g, '');
    var index = signature.indexOf('(');
    var name = index > -1 ? signature.substring(0, signature.indexOf('(')) : signature;
    var context = this;
    var method = context[name];
    //上下文中不存在函数定义,视为第一次定义
    if(method === undefined){
    context[name] = method = createMethodProxy(context, name);
    }else if(!method.Type || method.Type.type!='method'){
    //上下文存在的函数是原生函数,将这个函数作为默认函数存入列表
    var temp = method;
    context[name] = method = createMethodProxy(context, name);
    method.__functions__[name + '()'] = temp;
    }else{
    //如果上下文不同,创建新的重载方法并将已经存在的函数复制,这里主要解决类继承中子类与父类冲突的问题
    //如果上下文相同,直接将初始化标记设为false,待下次调用时重新初始化
    if(method.__context__ !== context){
    var temp = method;
    context[name] = method = createMethodProxy(context);
    for(var sign in temp.__functions__){
    method.__functions__[sign] = temp.__functions__[sign];
    }
    }else{
    method.__initialized__ = false;
    }
    }
    //将本次定义的函数添加到函数列表
    //先入为主策略
    if(comp){
    if(fn.__functions__){
    for(var key in fn.__functions__){
    if(key in method.__functions__){
    method.__functions__[key].__overridden__ = fn;
    }else{
    method.__functions__[key] = fn;
    }
    }
    }else{
    if(signature in method.__functions__){
    method.__functions__[signature].__overridden__ = fn;
    }else{
    method.__functions__[signature] = fn;
    }
    }
    }else{
    //后入为主策略
    if(fn.__functions__){
    for(var key in fn.__functions__){
    if(key in method.__functions__){
    fn.__functions__[key].__overridden__ = method;
    }
    method.__functions__[key] = fn.__functions__[key];
    }
    }else{
    if(signature in method.__functions__){
    fn.__overridden__ = method;
    }
    method.__functions__[signature] = fn;
    }
    }
    if(this.Type && this.Type.type == 'package'){
    return this;
    }else{
    return method;
    }
    };
    })();
    //类定义函数
    var createClass = (function(){
    var slice = Array.prototype.slice;
    var emptyFn = function(){};
    var createClass = function(name){
    return function(){
    this[name].apply(this, slice.call(arguments, 0));
    };
    }
    //用于调用被重写函数
    var baseCaller = function(){
    if(arguments.length){
    var args = slice.call(arguments, 0);
    return baseCaller.caller.__overridden__.apply(this, args);
    }else{
    return baseCaller.caller.__overridden__.call(this);
    }
    }
    //用于调用自身重载构造函数
    var selfCaller = function(){
    if(arguments.length){
    var args = slice.call(arguments, 0);
    return selfCaller.caller.__self__.apply(this, args);
    }else{
    return selfCaller.caller.__self__.call(this);
    }
    }
    var filter = {prototype:true, Type:true};
    //快速浅拷贝
    function clone(a){
    var fn = function(){};
    fn.prototype = a;
    return new fn;
    }
    //对象复制,替换存在的(后入为主)
    function replace(base, self){
    for(var key in self){
    if(!(key in filter)){
    if(typeof self[key] == 'function'){
    //如果子类函数包含重载签名或父类函数已经重载
    if(key.indexOf('(') > -1 || (base[key] && base[key].__functions__)){
    createMethod.call(base, key, self[key]);
    }else{
    //常规函数定义
    if(key in base){
    //记录重写信息
    self[key].__overridden__ = base[key];
    }
    base[key] = self[key];
    }
    }else{
    base[key] = self[key];
    }
    }
    }
    }
    //对象复制,只取补集(先入为主)
    function complement(self, base){
    for(var key in base){
    if(!(key in filter)){
    if(typeof base[key] == 'function'){
    if(key.indexOf('(') > -1 || (self[key] && self[key].__functions__)){
    createMethod.call(self, key, base[key], true);
    }else{
    if(key in self){
    //记录重写信息
    self[key].__overridden__ = base[key];
    }else{
    self[key] = base[key];
    }
    }
    }else if(!(key in self)){
    self[key] = base[key];
    }
    }
    }
    }
    return function(){
    //处理参数
    if(this.Type && this.Type.type == 'package'){
    if(arguments.length == 2){
    var name = arguments[0];
    var body = arguments[1];
    }else{
    var name = arguments[0];
    var config = arguments[1];
    var body = arguments[2];
    }
    }else{
    if(arguments.length == 1){
    var name = 'Anonymous';
    var body = arguments[0];
    }else{
    var name = 'Anonymous';
    var config = arguments[0];
    var body = arguments[1];
    }
    }
    //创建类的基础函数
    var clazz = createClass(name);
    //获取父类信息
    var baseClass;
    if(config && config.extend){
    baseClass = config.extend;
    }
    //如果传入的主体为函数,取其返回值
    if(typeof body == 'function'){
    body = body(clazz);
    }
    //处理静态成员
    if(body.Static){
    complement(clazz, body.Static);
    delete body.Static;
    body = body.Public||body;
    }else{
    body = body.Public||body;
    }
    //处理继承
    if(baseClass){
    //通过快速浅拷贝复制父类成员
    clazz.prototype = clone(baseClass.prototype);
    //继承静态成员
    complement(clazz, baseClass);
    //继承类成员
    complement(clazz.prototype, body);
    }else{
    //不存在继承
    clazz.prototype = {};
    complement(clazz.prototype, body);
    }
    //处理混合
    if(config && config.mixin){
    var mixin = config.mixin;
    if(mixin instanceof Array){
    for(var i=0; ireplace(clazz.prototype, mixin[i]);
    }
    }else{
    replace(clazz.prototype, mixin);
    }
    }
    //添加内置函数
    clazz.prototype.base = baseCaller;
    clazz.prototype.self = selfCaller;
    clazz.prototype.constructor = clazz;
    clazz.prototype.toString = customToString;
    clazz.toString = customToString;
    clazz.prototype.Class = clazz;
    if(clazz.prototype[name]){
    var constructor = clazz.prototype[name];
    if(constructor.__functions__){
    for(var key in constructor.__functions__){
    //存在重载时,添加自身引用,用于通过this.self调用重载构造函数
    constructor.__functions__[key].__self__ = constructor;
    //存在继承时,将父类的构造函数作为被重写的函数,配置给当前类的构造函数
    //用于通过base调用父类构造函数
    if(baseClass){
    constructor.__functions__[key].__overridden__ = baseClass.prototype[baseClass.Type.shortName];
    }
    }
    }else if(baseClass){
    clazz.prototype[name].__overridden__ = baseClass.prototype[baseClass.Type.shortName];
    }
    }else{
    clazz.prototype[name] = emptyFn;
    }
    //类型自描述信息
    //如果当前上下文是一个包,将类添加到包中
    if(this.Type && this.Type.type == 'package'){
    clazz.Type = {
    type:'class',
    name: this.Type.name+'.'+name,
    shortName: name,
    Package: this,
    Class: clazz,
    baseClass: baseClass
    }
    clazz.prototype.Type = {
    type: 'object',
    name: this.Type.name+'.'+name
    }
    //将类添加到包
    this[name] = clazz;
    //调用静态构造函数
    if(name in clazz){
    clazz[name].call(clazz);
    }
    //返回this用于链式调用
    return this;
    }else{
    //上下文不是包则直接返回
    clazz.Type = {
    type:'class',
    name: name,
    shortName: name,
    Class: clazz,
    baseClass: baseClass
    }
    clazz.prototype.Type = {
    type: 'object',
    name: name,
    baseClass: baseClass
    }
    if(name in clazz){
    clazz[name].call(clazz);
    }
    return clazz;
    }
    };
    })();
    //用于创建支持重载的普通对象
    var createObject = function(objects, config){
    var target;
    if(this.Type && this.Type.type == 'package'){
    target = this;
    }else{
    target = {};
    }
    if(typeof objects == 'string'){
    target = this[objects] = {};
    objects = config;
    }else if(typeof objects == 'function'){
    objects = objects();
    }
    for(var key in objects){
    if(typeof objects[key] == 'function' && (key.indexOf('(') > -1 || typeof target[key] == 'function')){
    createMethod.call(target, key, objects[key]);
    }else{
    target[key] = objects[key];
    }
    }
    if(this.Type && this.Type.type == 'package'){
    return this;
    }else{
    return target;
    }
    };
    //用于创建包
    var createPackage = (function(){
    var root = this;
    return function(package){
    var name = [];
    var path = package.split('.');
    var parent = root;
    for(var i=0; iname.push(path[i]);
    if(parent[path[i]]){
    parent = parent[path[i]];
    }else{
    var pack = {
    Class: createClass,
    Object: createObject,
    Function: createMethod,
    Package: createPackage,
    toString: customToString
    };
    pack.Type = {
    type: 'package',
    Package: pack,
    name: name.join('.')
    }
    parent = parent[path[i]] = pack;
    }
    }
    return parent;
    }
    })();
    //默认将Package暴露
    window.Package = createPackage;
    return {
    Package: createPackage,
    Class: createClass,
    Function: createMethod,
    Object: createObject
    };
    })();

    结束语:
    到这里,lang.js的应用和原理就介绍完毕了,该库在主流浏览器中均已测试通过,
    如果想使用lang.js,可以在这里免费下载,如发现什么问题,或有好的建议可以反馈给我。
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:面向对象 扩展库
    上一篇:jQuery 自定义函数写法分享_jquery 下一篇:一个JQuery操作Table的代码分享_jquery
    千万级数据并发解决方案

    相关文章推荐

    • 浅析nodejs项目中的package.json的常见配置属性• angular学习之聊聊两种类型的表单• 简单总结JavaScript事件• JavaScript怎么实现基础类型和对象一样有属性和方法• 完全掌握JavaScript的Date对象
    1/1

    PHP中文网