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

  • 相关阅读:
    VMware Workstation 15 安装教程
    Kail更新源、输入法、浏览器
    Kali Linux 下载、引导、安装
    dwr超时
    jsp获取web的跟路径
    java线程安全
    jsp快速回顾
    在web.xml中可以设置jsp标签吗?
    axis2--生成的wsdl文件方法的参数问题
    java删除文件
  • 原文地址:https://www.cnblogs.com/xkzy/p/3873361.html
Copyright © 2011-2022 走看看