在Javascript中,有没有办法检查函数参数的类型?我想编写一个名为checkTypes
的函数,它执行以下操作:
function checkTypes(typeArr){
//if the types do not match typeArr, throw an error
}
function exampleUsage(arr1, arr2, num1){
checkTypes("object", "object", "number");
//throw an error if the types do not match the corresponding elements
}
答案 0 :(得分:10)
您可以使用此帖Fixing the JavaScript typeof operator改编的typeOf
功能结合此功能:
function typeOf( obj ) {
return ({}).toString.call( obj ).match(/\s(\w+)/)[1].toLowerCase();
}
function checkTypes( args, types ) {
args = [].slice.call( args );
for ( var i = 0; i < types.length; ++i ) {
if ( typeOf( args[i] ) != types[i] ) {
throw new TypeError( 'param '+ i +' must be of type '+ types[i] );
}
}
}
function foo( a,b,c ) {
checkTypes( arguments, ['string', 'number', 'array'] );
return 'foo';
}
console.log( foo( 'a', 1, [2] ) ); //=> foo
console.log( foo( 1, 1, [2] ) );
//^ Uncaught TypeError: param 0 must be of type string
答案 1 :(得分:8)
在这种情况下,请勿使用typeof
。由于以下几个原因,这是有问题的:
typeof null // 'object'
typeof [] // 'object'
typeof 'foo' // 'string'
typeof new String('foo') // 'object'
'foo' == new String('foo') // true
相反,请使用Object::toString
:
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call('foo') // '[object String]'
Object.prototype.toString.call(new String('foo')) // '[object String]'
装饰者会满足您的要求:
var getType = function(value) {
return Object.prototype.toString.call(value)
.replace(/^\[object |\]$/g, '').toLowerCase();
};
var checkTypes = function(types, fn) {
return function() {
var args = Array.prototype.slice.call(arguments, 0);
for (var idx = 0; idx < types.length; idx += 1) {
var expected = types[idx];
var received = getType(args[idx]);
if (received != expected) {
throw new TypeError('expected ' + expected + '; received ' + received);
}
}
fn.apply(null, args);
};
};
var exampleUsage = checkTypes(['array', 'array', 'number'], function(arr1, arr2, num1) {
console.log('arr1:', arr1);
console.log('arr2:', arr2);
console.log('num1:', num1);
});
用法示例:
exampleUsage([], [], 0);
// arr1: []
// arr2: []
// num1: 0
exampleUsage([], [], 'foo');
// TypeError: expected number; received string
答案 2 :(得分:3)
您可以使用typeof
的修改版本和arguments
伪数组来获取每个参数类型,并将其与您所需的类型集进行比较:
// from Doug Crockford http://javascript.crockford.com/remedial.html
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (Object.prototype.toString.call(value) == '[object Array]') {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
function checkTypes(argList, typeList) {
for (var i = 0; i < typeList.length; i++) {
if (typeOf(argList[i]) !== typeList[i]) {
throw 'wrong type: expecting ' + typeList[i] + ", found " + typeOf(argList[i]);
}
}
}
工作演示:http://jsfiddle.net/jfriend00/ywyLe/
示例用法:
function exampleUsage(arr1, arr2, num1){
//throw an error if the types do not match the corresponding elements
checkTypes(arguments, ["array", "array", "number"]);
}
答案 3 :(得分:0)
您正在寻找typeof运营商。
答案 4 :(得分:0)
大多数事物的typeof函数返回对象,
alert(typeof("this is string")); /* string */
alert(typeof(1234)); /* number */
alert(typeof([])); /* object */
alert(typeof({})); /* object */
alert(typeof(new Date)); /* object */
alert(typeof(function(){})); /* function */
但是jQuery可以通过这个函数识别jQuery.type(obj) http://api.jquery.com/jQuery.type/
答案 5 :(得分:0)
如果有人在寻找类似需求的环境解决方案,我可以推荐typeof-arguments包。
const checkTypes = require('typeof-arguments');
function exampleUsage(arr1, arr2, num1){
checkTypes(arguments,["object", "object", "number"]);
//throw an error if the types do not match the corresponding elements
}
答案 6 :(得分:-4)
JavaScript对类型不利。 此外,您无法从调用函数中神奇地访问父函数参数。
如果您不想头疼,请使用一些简单的库来检查类型。
例如,使用underscore.js,您可以编写如下内容:
function exampleUsage(arr1, arr2, num1) {
if(!_.isArray(arr1) || !_.isArray(arr2) || !_.isNumber(num1) {
throw "Wrong types"
}
// do other stuff
}
你可能害怕类型,因为你可能不熟悉动态语言。您会看到它没有看起来那么糟糕,但是JavaScrip很糟糕(出于很多其他原因)