zoukankan      html  css  js  c++  java
  • javascript函数参数、返回值类型检查

    实现带参数、返回值类型声明的js函数:

    类型定义:
    window.Str = Type.Str = Type.define('STRING', Type.isStr);
    var Per = Type.define('PERSON', function(p){
        return p && p.type === 'person' && p.name;
    });

    定义函数:
    var addStr = Str(function(a, b){
      return a + b;
    }, Str, Str);
    运行:
    addStr('1', 1);
    则报错:
    TypeError: Unexpected argument, expecting STRING (arg[1])

    定义函数:
    var addToStr = Str(function(a, b){
      return a + b;
    });
    运行:
    addToStr(1, 1);
    则报错:
    TypeError: Unexpected result, expecting STRING
    1. [代码]define Type     

    /*
     * The main class: Type
     */
     
    var Type = function(){
        this.author = {
            name: 'nighca',
            email: 'nighca@live.cn'
        };
    };
    2. [代码]type mehods     

    /*
     * func define/destroy to define/destroy a type
     */
     
    Type.__defined__ = {};
     
    Type.define = function(name, check, override){
        var Type = this;
        if(!Type.isStr(name) || !Type.isFunc(check)){
            throw new TypeError('Param error');
        }else if(!override && this.__defined__[name]){
            throw new Error('Type ' + name + ' already exists');
        }else{
            var funcCreator = function(func){
                var argumentTypes = Array.prototype.slice.call(arguments, 1);
                var wrapper = function(){
                    for (var i = 0, l = argumentTypes.length; i < l; i++) {
                        if(argumentTypes[i] && !argumentTypes[i].check(arguments[i])){
                            throw new TypeError(
                                'Unexpected argument, expecting ' +
                                argumentTypes[i].typeName +
                                ' (arg[' + i + '])'
                            );
                        }
                    };
                    var ret = func.apply(this, arguments);
                    if(!check(ret)){
                        throw new TypeError('Unexpected result, expecting ' + name);
                    }
                    return ret;
                };
                wrapper.toString = function(){
                    return func.toString();
                };
                return wrapper;
            };
            funcCreator.check = check;
            funcCreator.typeName = name;
            funcCreator.constructor = Type;
            funcCreator.__proto__ = Type.prototype;
     
            return this.__defined__[name] = funcCreator;
        }
    };
     
    Type.isType = function(t){
        return t && t.constructor === Type;
    }
     
    Type.mix = function(name){
        var types, type;
        if(!Type.isStr(name)){
            types = Array.prototype.slice.call(arguments, 0);
            name = null;
        }else{
            types = Array.prototype.slice.call(arguments, 1);
        }
     
        if(types.length < 2){
            throw new Error('Params error');
        }
        var i, l;
        for (i = 0, l = types.length; i < l; i++) {
            if(!Type.isType(types[i])){
                throw new TypeError('Param not a type');
            }
        }
     
        if(!name){
            name = 'MIX_OF_' + types[0].typeName;
            for (i = 1, l = types.length; i < l; i++) {
                name += '_' + types[i].typeName;
            }
            name += '@' + Date.now();
        }
     
        var checker = function(obj){
            for (var i = 0, l = types.length; i < l; i++) {
                if(!types[i].check(obj)){
                    return false;
                }
            }
            return true;
        };
     
        return Type.define(name, checker);
    };http://www.huiyi8.com/jianbihua/
    简笔画大全 
    Type.any = function(name){
        var types, type;
        if(!Type.isStr(name)){
            types = Array.prototype.slice.call(arguments, 0);
            name = null;
        }else{
            types = Array.prototype.slice.call(arguments, 1);
        }
     
        if(types.length < 2){
            throw new Error('Params error');
        }
        var i, l;
        for (i = 0, l = types.length; i < l; i++) {
            if(!Type.isType(types[i])){
                throw new TypeError('Param not a type');
            }
        }
     
        if(!name){
            name = 'ANY_OF_' + types[0].typeName;
            for (i = 1, l = types.length; i < l; i++) {
                name += '_' + types[i].typeName;
            }
            name += '@' + Date.now();
        }
     
        var checker = function(obj){
            for (var i = 0, l = types.length; i < l; i++) {
                if(types[i].check(obj)){
                    return true;
                }
            }
            return false;
        };
     
        return Type.define(name, checker);
    };
     
    Type.isDefined = function(name){
        return !!this.__defined__[name];
    };
     
    Type.destroy = function(name){
        if(!Type.isStr(name)){
            throw new TypeError('Param error');
        }
     
        var type = this.__defined__[name];
        if(type){
            type = null;
            delete this.__defined__[name];
        }
    };
     
    Type.prototype.suicide = function(){
        this.constructor.destroy(this.typeName);
    };​
    3. [代码]some help funcs     

    /*
     * Some funcs to judge obj type
     */
     
    Type.toString = function(){
        return JSON ? JSON.stringify(new this()) : '>_<';
    };
     
    Type.format = function(obj){
        return Object.prototype.toString.call(obj);
    };
     
    Type.isNum = function(obj){
        return typeof obj === 'number' || Type.format(obj) === '[object Number]';
    };
     
    Type.isStr = function(obj){
        return typeof obj === 'string' || Type.format(obj) === '[object String]';
    };
     
    Type.isFunc = function(obj){
        return typeof obj === 'function' || Type.format(obj) === '[object Function]';
    };
     
    Type.isBool = function(obj){
        return typeof obj === 'boolean' || Type.format(obj) === '[object Boolean]';
    };
     
    Type.isArr = function(obj){
        return Type.format(obj) === '[object Array]';
    };
     
    Type.isReg = function(obj){
        return Type.format(obj) === '[object RegExp]';
    };
     
    Type.isObj = function(obj){
        return Type.format(obj) === '[object Object]';
    };
     
    Type.isUndef = function(obj){
        return typeof obj === 'undefined';
    };
     
    Type.isNul = function(obj){
        return Type.format(obj) === '[object Null]';
    };
     
    Type.isVoid = function(obj){
        return true;
    };
    4. [代码]Some default types    
    /*
     * Some default types binded to window & Type
     */
     
    window.Num = Type.Num = Type.define('NUMBER', Type.isNum);
     
    window.Str = Type.Str = Type.define('STRING', Type.isStr);
     
    window.Func = Type.Func = Type.define('FUNCTION', Type.isFunc);
     
    window.Bool = Type.Bool = Type.define('BOOLEAN', Type.isBool);
     
    window.Arr = Type.Arr = Type.define('ARRAY', Type.isArr);
     
    window.Reg = Type.Reg = Type.define('REGEXP', Type.isReg);
     
    window.Obj = Type.Obj = Type.define('OBJECT', Type.isObj);
     
    window.Undef = Type.Undef = Type.define('UNDEFINED', Type.isUndef);
     
    window.Nul = Type.Nul = Type.define('NULL', Type.isNul);
     
    window.Void = Type.Void = Type.define('VOID', Type.isVoid);

  • 相关阅读:
    什么是webview
    juqery.fn.extend和jquery.extend
    LeetCode
    5. Longest Palindromic Substring
    42. Trapping Rain Water
    11. Container With Most Water
    621. Task Scheduler
    49. Group Anagrams
    739. Daily Temperatures
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/xkzy/p/3873361.html
Copyright © 2011-2022 走看看