JavaScript名前空間、関数パラメータタイプの重載の実現

7155 ワード

突然思いついて書いたものは、func({arg 1:xxx,arg 2:xxx}が適用されない場合に使うと考えられます.
 



    
    
    
    
        (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);
        })();
    


    





 
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 {
                return 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 () {
                    return 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);
        }
    });
})();
転載先:https://www.cnblogs.com/dashublog/p/3959388.html