实现带参数、返回值类型声明的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);

javascript函数参数、返回值类型检查的更多相关文章

  1. JAVA函数的返回值类型详解以及生成随机数的例题

    函数的四要素:函数名.输入.输出(返回).加工. 函数分为两种:一种是有返回值得函数,一种是没有返回值的函数. 1. 定义:没有返回值的函数:(当我不需要函数的计算结果再拿出来进行运算的时候,我就不需 ...

  2. Swift 定义函数 参数 返回值

    定义多参数函数 - 用func声明函数  func name(parameters) -> return type { function body } func halfOpenRangeLen ...

  3. Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...

  4. MATLAB importdata函数返回值类型

    importdata函数是MATLAB中I/O文件操作的一个重要函数.需要注意的是,针对不同的文件内容,importdata函数的返回值类型也有所不同. MATLAB帮助文档中的详细说明如下: Bas ...

  5. 请为main函数提供返回值

    很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的.C/C++ 中从来没有定义过void main( ).C++ 之父 Bjarne Stroustrup 在他的主页上的 ...

  6. php7函数,声明,返回值等新特性介绍

    使用 ... 运算符定义变长参数函数 (PHP 5 >= 5.6.0, PHP 7) 现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数. functi ...

  7. c++ 模板类,方法返回值类型是typedef出来的,或者是auto,那么此方法在类外面如何定义?

    c++ 模板类,方法返回值类型是typedef出来的,或者是auto,那么此方法在类外面如何定义? 比如方法max1的返回值是用typedef定义出来的mint,那么在类外如何定义这个方法呢? tem ...

  8. javascript . 03 函数定义、函数参数(形参、实参)、函数的返回值、冒泡函数、函数的加载、局部变量与全局变量、隐式全局变量、JS预解析、是否是质数、斐波那契数列

    1.1 知识点 函数:就是可以重复执行的代码块 2.  组成:参数,功能,返回值 为什么要用函数,因为一部分代码使用次数会很多,所以封装起来, 需要的时候调用 函数不调用,自己不会执行 同名函数会覆盖 ...

  9. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

随机推荐

  1. RF新手常见问题总结--(基础篇)

    1. 经常有人问这个元素找不到,一般先排除这两个地方,再自己找找A:是否等待了足够的时间让元素加载 (增加sleep xx, wait Until xxx)B:  仔细查查,这个元素是否进入到另一个f ...

  2. jQuery的对象访问函数(get,index,size,each)

    1.get() 元素集合 取得所有匹配的 DOM 元素集合. 这是取得所有匹配元素的一种向后兼容的方式(不同于jQuery对象,而实际上是元素数组). 如果你想要直接操作 DOM 对象而不是 jQue ...

  3. 牛客网暑期ACM多校训练营(第九场) A题 FWT

    链接:https://www.nowcoder.com/acm/contest/147/A来源:牛客网 Niuniu has recently learned how to use Gaussian ...

  4. POJ 3254 【状态压缩DP】

    题意: 给一块n*m的田地,1代表肥沃,0代表贫瘠. 现在要求在肥沃的土地上种草,要求任何两个草都不能相邻. 问一共有多少种种草的方法. 种0棵草也是其中的一种方法. n和m都不大于12. 思路: 状 ...

  5. Java读取文件时中文路径处理

    读取文件路径时可能存在以下情况: 1.空格,如果出现空格会转变成“%20” 2.中文路径,如果出现中文路径会变成URI编码“%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b” ...

  6. Failed to execute 'toDataURL' on 'HTMLCanvasElement,在canvas.toDataURL()执行时候报错解决方案

    添加跨域条件   crossorigin="anonymous" [Redirect at origin 'http://xxx.xx.com' has been blocked ...

  7. Linux 修改终端命令提示符颜色

    相信很多人已经看厌了Linux已成不变的命令提示符的颜色,多数人要么使用默认的绿色,要么在使用PUTTY的时候设置成绿色的,不知道是否有人想到提示符可以设置成其他的颜色呢,本文就说明命令提示符变量PS ...

  8. 谈一谈关于NODE里的N管理

    模块可能与当前的NODE版本不和,NODE升级问题? 一切尽在掌握 1.首先设置好PATH(你安装的目录) Debian系列: sudo gedit /etc/profile Redhat系列: su ...

  9. M公司入职记

    非常遗憾,我又跳槽了,到传说中的M公司,第一天就体会到了,神马叫差距. 要求9点30到,提前10分钟到了前台.前台MM懵懂的跟我说入职找人事,好吧. 电话联系相关人等,等到10点左右,被引导到一位不知 ...

  10. 聚合类新闻client产品功能点详情分析

    产品功能点 功能 今日头条 百度新闻 鲜果 ZAKER 媒体订阅 × √ ★ ★ 个性化内容推荐 ★ √ × × 个性化订阅(RSS) × × ★ × 视频新闻 × × × × 评论盖楼 √ √ √ ...