`

JavaScript函数重载模拟

阅读更多
转自:http://www.cnblogs.com/simayixin/archive/2011/03/28/1997519.html


我们从结果向实现推,首先看我们要实现什么样的效果:

css(hi,"color","red")
css([hi,hello],"color","red")
css(hi,{"border":"1px solid #000","width":"200px"})
var color = css(hi,"color")

这是很常见的写法,然后看我们希望怎么写:

Overload("css",window,
         {
             "object,string,string" : function(el,key,val){
                 el.style[key] = val;
             }
             ,"array,string,string" : function(els,key,val){
                 for(var i=0;i<els.length;i++){
                    els[i].style[key] = val;
                 }
             }
             ,"object,object" : function(el,kv){
                for(var i in kv){
                    el.style[i] = kv[i];   
                }
             }
             ,"object,string" : function(el,key){
                 return el.style[key];
             }
});
接下来,看实现:

/*
    JavaScript函数重载模拟
    name : 函数名
    bind : 函数需要绑定到的对象
    fn_objs : 键值对函数对象,键位以逗号隔开的类型(number,string,object,undefined,boolean,array,*)字符串,其中*为万能类型,值为对应的函数,
    如:{"string,string":function(x,y){},"string,number":functioin(x,y){}}
*/
var Overload = function(name,bind,fn_objs){
    var dict_name = "_"+name+"_dict",dict;
    dict = bind[dict_name] = bind[dict_name] || {};
    
    for(var i in fn_objs){
        dict[i] = fn_objs[i];  
    }
    
    var is_match = function(x,y){
        if(x==y)return true;
        if(x.indexOf("*")==-1)return false;
    
        var x_arr = x.split(","),y_arr = y.split(",");
        if(x_arr.length != y_arr.length)return false;
    
        while(x_arr.length){
            var x_first =  x_arr.shift(),y_first = y_arr.shift();
            if(x_first!="*" && x_first!=y_first)return false;
        }
        return true;
    };
    
    bind[name] = function(){
        var args = arguments,args_len = args.length,args_types=[],args_type,match_fn = function(){};
        for(var i=0;i<args_len;i++){
            var type = typeof args[i];
            type=="object" &&  (args[i] instanceof Array) && (type="array");
            args_types.push(type);
        }
        args_type = args_types.join(",");
        for(var k in dict){
            if(is_match(k,args_type)){
                match_fn = dict[k];
                break;
            }
        }
        return match_fn.apply(this,args);
    };
};
因为采用typeof来动态监测参数类型,而typeof又只能检测到的值只有(number,string,object,undefined,boolean),所以类型的制定只能从这些值中设定,实现中还加入了万能类型"*",由于array属于常用类型, 所以又特别添加了对array类型的支持。

基本原理是:将以类型串为键,函数为值的字典挂到需要绑定的对象上,命名为"_"+fn_name+"_dict",可用bind["_"+fn_name_"_dict"]来访问此对象,接着生成一个函数,在函数里靠判断arguments生成的类型串来从上述字典中匹配到相应的函数。

------------------------------------------------------------------------------------------------------------------

上面的写法 ,始终不好看,有如下改进:

Overload = function(fn_objs){
    var is_match = function(x,y){
        if(x==y)return true;
        if(x.indexOf("*")==-1)return false;
    
        var x_arr = x.split(","),y_arr = y.split(",");
        if(x_arr.length != y_arr.length)return false;
    
        while(x_arr.length){
            var x_first =  x_arr.shift(),y_first = y_arr.shift();
            if(x_first!="*" && x_first!=y_first)return false;
        }
        return true;
    };
    var ret = function(){
        var args = arguments
        ,args_len = args.length
        ,args_types=[]
        ,args_type
        ,fn_objs = args.callee._fn_objs
        ,match_fn = function(){};
        
        for(var i=0;i<args_len;i++){
            var type = typeof args[i];
            type=="object" && (args[i].length>-1) && (type="array");
            args_types.push(type);
        }
        args_type = args_types.join(",");
        for(var k in fn_objs){
            if(is_match(k,args_type)){
                match_fn = fn_objs[k];
                break;
            }
        }
        return match_fn.apply(this,args);
    };
    ret._fn_objs = fn_objs;
    return ret;
};

String.prototype.format = Overload({
    "array" : function(params){
        var reg = /{(\d+)}/gm;
        return this.replace(reg,function(match,name){
            return params[~~name];
        });
    }
    ,"object" : function(param){
        var reg = /{([^{}]+)}/gm;
        return this.replace(reg,function(match,name){
            return param[name];
        });
    }
});
分享到:
评论

相关推荐

    JavaScript函数重载操作实例浅析

    在面试中,面试官询问了关于JavaScript函数重载的实现方法,这表明在实际开发中,即使语言本身不支持,我们也可以通过某种方式来模拟函数重载的功能。面试者首先想到了使用arguments对象的length属性来判断实际传入...

    让 JavaScript 轻松支持函数重载 (Part 2 - 实现)

    本文介绍了一种实现JavaScript函数重载的方法,主要依赖于一个名为Overload的静态类。 首先,我们需要理解什么是函数重载以及在不同编程语言中是如何实现它的。举个例子,在C++或Java中,可以通过在同一个作用域内...

    javascript函数重载解决方案分享

    通过这种方式,尽管 JavaScript 不直接支持函数重载,但我们仍可以利用 `arguments` 对象和类型检查来模拟这一功能,从而在不同场景下实现类似重载的行为。需要注意的是,这种方法虽然实用,但可能会使代码变得复杂...

    JavaScript重载函数实例剖析_.docx

    #### 二、JavaScript中的重载模拟 ##### 2.1 基于参数数量的模拟 JavaScript中有一个特殊的变量`arguments`,它是一个类数组对象,包含了传递给函数的所有参数。通过检查`arguments`的长度(`arguments.length`)...

    让JavaScript 轻松支持函数重载 (Part 1 – 设计)

    说支持,是因为JavaScript函数对参数列表不作任何限制,可以在函数内部模拟对函数重载的支持。 实际上,在很多著名的开源库当中,我们都可以看到函数内部模拟重载支持的设计。例如说jQuery的jQuery.extend方法,就是...

    JAVASCRIPT 函数手册.rar

    13. **函数重载**:JavaScript不支持真正的函数重载,但可以通过检查参数类型或数量来模拟。 14. **立即执行函数表达式 (IIFE)**: `(function() { /* code */ })();`,这种模式可以避免函数污染全局作用域。 15. ...

    通过实例理解javascript中没有函数重载的概念

    尽管这样,开发者可以通过其他方式(例如使用对象参数或利用ES6的默认参数)来模拟函数重载的行为。 7. ECMAScript标准 ECMAScript是JavaScript的标准化版本,它提供了JavaScript语言规范。根据ECMAScript的规范,...

    详解JS函数重载

    模拟JavaScript函数重载通常涉及以下几种方法: 1. 根据参数个数进行重载 2. 根据参数类型进行重载 基于参数个数进行重载相对简单。通过arguments.length属性,我们可以获取实际传入的参数个数。然后根据这个个数...

    JS函数重载的解决方案

    综上所述,虽然JavaScript本身不支持函数重载,但通过使用arguments对象、typeof运算符和constructor属性,我们可以在一定程度上模拟出函数重载的效果。这要求我们明确地检查每个参数的类型和个数,并据此来调用不同...

    JavaScript中的函数重载深入理解

    函数重载的概念在JavaScript中虽然没有直接的支持,但可以通过其他方式模拟实现。一种常见的做法是使用函数参数的数量或类型来区分不同的函数逻辑,即所谓的“伪重载”: ```javascript function sum() { if ...

    JavaScript重载函数实例剖析

    我们来简单用两种方式来”模拟”下重载函数。 2.根据参数的个数来判断 javascript的函数中有一个叫arguments的变量,是记录参数的一个数组,我们可以用这个来判断参数的个数,然后分别执行不同的内容,就是同一个...

    为JavaScript添加重载函数的辅助方法

    虽然JavaScript本身不直接支持像C++或Java那样的函数重载,但我们可以通过模拟的方式来实现类似的功能。 在JavaScript中,实现函数重载通常依赖于检查`arguments`对象,这是一个类数组对象,包含了函数调用时传入的...

    【JavaScript源代码】JavaScript的function函数详细介绍.docx

    在上面的例子中,`arguments`对象帮助我们根据传入参数的数量执行不同的操作,模拟了类似Java中的函数重载。 然而,JavaScript并不支持真正的函数重载,即同一函数名根据不同的参数列表执行不同的功能。我们可以...

    JavaScript常用函数列表

    以上列举的JavaScript函数涵盖了从用户交互到页面管理、数学运算、字符串操作以及浏览器信息获取等多个方面,是开发网页应用时不可或缺的工具集。掌握这些函数的使用方法,对于提升网页的交互性和功能性具有重要意义...

    添加JavaScript重载函数的辅助方法2

    在JavaScript语言中,函数重载并不是一个内置的特性,但通过一些技巧可以模拟出这一功能。以下是对知识点的详细阐述: 1. 重载函数的概念: 重载函数是指在同一作用域内,可以存在多个同名函数,但这些函数的参数...

    JavaScript 基本语法 高级语法 自定义函数下载

    3. **函数重载**:虽然JavaScript不直接支持函数重载,但可以通过检查传入参数的类型或数量来模拟实现。 4. **高阶函数**:接受函数作为参数或返回函数的函数,如`map`、`filter`、`reduce`等。 5. **函数柯里化**...

    overload-js:javascript中的函数重载

    JavaScript 中的函数重载为 3.9KB,压缩为 1.4KB。 提供工具来模拟大多数严格类型语言中存在的。 防止难以阅读和维护的混乱、冗长、if 语句、类型检查函数。 受和启发的样式和 API。 npm install overload-js ...

Global site tag (gtag.js) - Google Analytics