JavaScript命名空间、函数参数类型重载的实现

突然心血来潮写的东西,可以考虑在func({arg1: xxx, arg2: xxx})不适用的情况下使用。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>命名空间、参数类型重载</title>
    <script type="text/javascript" src="arg-func.js"></script>
    <script type="text/javascript">
        (function () {
            // 支持的参数类型:boolean, number, string, function, array, object,其中object类型的重载函数可被其它类型对应重载函数找不到的时候调用
            var MyFuncs = {
                ‘myNamespace.exampleFunc(string str, number num)‘: function (str, num) {
                    alert(‘str: ‘ + str + ‘ num: ‘ + num);
                },
                ‘myNamespace.exampleFunc(number num)‘: function (num) {
                    alert(‘num: ‘ + num);
                },
                ‘myNamespace.exampleFunc(array)‘: function (arr) {
                    alert(‘arr: ‘ + arr);
                },
                ‘myNamespace.exampleFunc(object)‘: function (obj) {
                    alert(‘object: ‘ + obj);
                },
                ‘myNamespace.exampleFunc()‘: function () {
                    alert(‘无参数重载‘);
                }
            };

            ArgFunc.parse(MyFuncs);
        })();
    </script>
</head>
<body>
    <input type="button" value="myNamespace.exampleFunc(‘abc‘,123)" onclick="myNamespace.exampleFunc(‘abc‘, 123)" /><br />
    <input type="button" value="myNamespace.exampleFunc(123)" onclick="myNamespace.exampleFunc(123)" /><br />
    <input type="button" value="myNamespace.exampleFunc([1,2,3])" onclick="myNamespace.exampleFunc([1, 2, 3])" /><br />
    <input type="button" value="myNamespace.exampleFunc()" onclick="myNamespace.exampleFunc()" /><br />
    <input type="button" value="myNamespace.exampleFunc(false)" onclick="myNamespace.exampleFunc(false)" /><br />
    <input type="button" value="myNamespace.exampleFunc(‘abc‘)" onclick="myNamespace.exampleFunc(‘abc‘)" /><br />
</body>
</html>

arg-func.js:

(function () {
    if (!String.prototype.trim) {
        String.prototype.trim = function () {
            return this.replace(/(^\s+)|(\s+$)/g, ‘‘);
        };
    }

    var TYPE = { EMPTY: ‘empty‘, BOOLEAN: ‘boolean‘, NUMBER: ‘number‘, STRING: ‘string‘, FUNCTION: ‘function‘, ARRAY: ‘array‘, OBJECT: ‘object‘ };
    function getType(o) {
        if (o === undefined) { return TYPE.EMPTY; }
        if (o === null) { return TYPE.OBJECT; }
        switch (typeof (o)) {
            case TYPE.BOOLEAN: return TYPE.BOOLEAN;
            case TYPE.NUMBER: return TYPE.NUMBER;
            case TYPE.STRING: return TYPE.STRING;
            case TYPE.FUNCTION: return TYPE.FUNCTION;
        }
        switch (Object.prototype.toString.call(o)) {
            case ‘[object Array]‘: return TYPE.ARRAY;
            default: return o ? TYPE.OBJECT : TYPE.EMPTY;
        }
    }

    var ArgFunc = {
        findFunc: function (args, funcLink) {
            if (!args || args.length == 0) {
                return funcLink ? funcLink._func : null;
            }
            if (!funcLink) {
                return null;
            }
            var index = arguments[2] || 0;
            var argType = getType(args[index]);
            var func, nextFunc = funcLink[argType];
            if (index + 1 < args.length) {
                func = ArgFunc.findFunc(args, nextFunc, index + 1);
                if (!func) {
                    nextFunc = funcLink[TYPE.OBJECT];
                    func = ArgFunc.findFunc(args, nextFunc, index + 1);
                }
            } else {
                func = nextFunc ? nextFunc._func : null;
                if (!func) {
                    nextFunc = funcLink[TYPE.OBJECT];
                    func = nextFunc ? nextFunc._func : null;
                }
            }
            return func;
        },
        applyFunc: function (wrapperFunc, args) {
            var funcLink = wrapperFunc._funcs;
            var func = ArgFunc.findFunc(args, funcLink);
            if (!func) {
                throw ‘没有找到参数类型匹配的重载方法‘;
            } else {
                func.apply(this, args);
            }
        },
        analyseNamespace: function (fullName, upperNamespace) {
            var namespace = upperNamespace || window;
            var parts = fullName.split(‘.‘);
            var name = parts.pop();
            for (var i = 0, part; part = parts[i]; i++) {
                if (namespace[part] === undefined) {
                    namespace[part] = {};
                }
                namespace = namespace[part];
            }
            return { namespace: namespace, name: name };
        },
        parseSingle: function (format, func, namespace) {
            var lp = format.indexOf(‘(‘), rp = format.indexOf(‘)‘);
            var name = format.substring(0, lp);
            var argTypes = format.substring(lp + 1, rp).split(‘,‘);
            for (var i = 0, len = argTypes.length; i < len; i++) {
                argTypes[i] = argTypes[i].trim().split(/ +/)[0];
            }
            if (argTypes.length == 1 && argTypes[0].length == 0) {
                argTypes.pop();
            }

            var nsnn = ArgFunc.analyseNamespace(name, namespace);
            namespace = nsnn.namespace;
            name = nsnn.name;

            var wrapperFunc = namespace[name];
            if (wrapperFunc === undefined) {
                wrapperFunc = namespace[name] = function () {
                    ArgFunc.applyFunc(wrapperFunc, arguments);
                };
                wrapperFunc._funcs = {};
            }

            var funcLink = wrapperFunc._funcs;
            for (var i = 0, argType; argType = argTypes[i]; i++) {
                if (funcLink[argType] === undefined) {
                    funcLink[argType] = { _func: null };
                }
                funcLink = funcLink[argType];
            }
            funcLink._func = func;
        },
        parseArray: function (funcs, namespace) {
            for (var i = 0, func; func = funcs[i]; i++) {
                ArgFunc.parseSingle(func[0], func[1], namespace);
            }
        },
        parseObject: function (funcs, namespace) {
            for (var format in funcs) {
                ArgFunc.parseSingle(format, funcs[format], namespace);
            }
        }
    };

    ArgFunc.parseObject({
        ‘ArgFunc.parse(object funcs, object namespace)‘: function (funcs, namespace) {
            ArgFunc.parseObject(funcs, namespace);
        },
        ‘ArgFunc.parse(object funcs)‘: function (funcs) {
            ArgFunc.parseObject(funcs, window);
        },
        ‘ArgFunc.parse(array funcs, object namespace)‘: function (funcs, namespace) {
            ArgFunc.parseArray(funcs, namespace);
        },
        ‘ArgFunc.parse(array funcs)‘: function (funcs) {
            ArgFunc.parseArray(funcs, window);
        },
        ‘ArgFunc.parse(string format, function func, object namespace)‘: function (format, func, namespace) {
            ArgFunc.parseSingle(format, func, namespace);
        },
        ‘ArgFunc.parse(string format, function func)‘: function (format, func) {
            ArgFunc.parseSingle(format, func);
        }
    });
})();
时间: 2024-10-12 10:15:52

JavaScript命名空间、函数参数类型重载的实现的相关文章

JavaScript函数命名空间、参数类型重载实现

有时候使用doFunc({arg1: xxx, arg2:xxx});不方便,还是得在参数表重载,而重载情况又多种多样弄得晕头转向,结果就试着写了这么个东西,也不知道有没有地方能用上: <!DOCTYPE html> <html lang="zh"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

VBA自定义函数参数类型不符的错误

作者:iamlaosong 1.问题提出 编程中发现一个问题,系统总是提示编译错误,ByRef 参数类型不符, 可实际上参数定义没问题,原因在哪儿呢? 2.问题环境 假定函数定义如下: Function get_kind(addr As String) As Integer ...... End Function 调用过程: Sub check_address() Dim addr, new_addr(10000) As String ...... addr = new_addr(i) ....

c++函数参数类型-值,指针,引用

    以" 值传递"方式向函数传递参数 在编写个人函数的时候,你将会受到C++中的一条基本的原则的限制:在默认的情况下,变量只能以值传递的方式传递给函数.这句话的意思是:被传递到函数的只是变量的值,永远不是变量的本身. 例如: void changeValue(int originalValue,int newValue){     originalValue = newValue;   }      int main(){     int myNum=20;     changeV

Python 函数参数类型大全(非常全!!!)

Python 函数参数类型大全(非常全!!!) 1.在python编写程序里面具有函数文档,它的主要作用是为了让别人可以更好的理解你的函数,所以这是一个好习惯,访问函数文档的方式是: MyFunction.__doc__ 2.python编写程序函数的时候具有两类参数: 形式参数(形参)及其实际参数(实参). 跟绝大部分编程语言一样,形参指的是函数创建和定义过程中小括号里的参数,而实参指的是函数在调用过程中传递进去的参数. 3.关键字参数,是指函数在调用的时候,带上参数的名字去指定具体调用的是哪

python函数参数类型及其顺序

根据inspect模块官文文档中关于函数参数类型的相关说明,python函数参数共有五种类型,按顺序分别为:POSITIONAL_ONLY.POSITIONAL_OR_KEYWORD.VAR_POSITIONAL.KEYWORD_ONLY.VAR_KEYWORD.如图: POSITIONAL_ONLY:参数值必须以位置参数的形式传递.python没有明确的语法来定义POSITIONAL_ONLY类型的参数,但很多内建或扩展模块的函数中常常会接收这种参数类型,实际使用中不多见,这里暂不考虑. PO

C++_第七章函数的基本知识_求阶乘的子函数_ 函数参数类型为数组_ 求数组内所有元素和、部分元素和的方法_实现了先从键盘输入到一个数组中,再用for循环取读出数组中的元素 for循环也可以用break来结束循环的

/* 第七章函数的基本知识 */ /*01)c++对于返回值有一定的限制:可以是常量.变量.指针.结构对象或表达式,但不可以是数组02)c++返回数组的方法:将数组作为结构会对象组成部分来返回03)函数遇到return则结束该函数04)如果一个函数的两房额参数类型相同,则必须分别制定每个参数的类型,而不能像声明常规变量那样,将声明组合在一起05)*/ //本代码注意double类型的写法以及double和int类型数据的转换 1 #include <iostream> 2 3 void che

PowerShell控制台输出符号+函数参数类型指定+文本内容读取

There are several ways: Write-Host: Write directly to the console, not included in function/cmdlet output. Allows foreground and background colour to be set. Write-Debug: Write directly to the console, if $DebugPreference set to Continue or Stop. Wri

Javascript - Jquery - 函数参数

函数参数(Parameter Mapping) 多参数 当一个函数具有多个参数时,如果我们在调用该函数时传递一大堆参数进去,而有些参数并不是必须的,代码看起来就有点混乱,此时可以使用匿名对象来解决.将参数作为匿名对象的属性,然后将匿名对象作为函数的参数即可. 参数替换 函数内部可以定义一个对象,设置对象的属性就是设置函数参数的默认值. function aa(options) { //配置默认参数 var param = { gender: 'man', age: 18 }; //extend方

pycahrm使用docstrings来指定变量类型、返回值类型、函数参数类型

py里面不需要显示声明类型,这和java c这些静态语言不同,虽然python这样做少了一些代码和写代码的困难度,但还是非常多的弊端的,运行速度 代码安全, 这些都是语言本身带来的本的弊端,这些没办法没办法弥补(说用c扩展和加入大量if isinstance来判断类型的,这是不好的不方便的).但下面这两种却是可以通过docstrings来弥补的. 1.没有类型就给函数(或者方法)调用者带来麻烦,这个函数怎么用,这个参数代表什么,需要传一个什么样的参数来调用这个函数,函数返回什么东西,这都对代码阅