这是对SO问题的回答:
function typedFunction(paramsList, f){
//optionally, ensure that typedFunction is being called properly -- here's a start:
if (!(paramsList instanceof Array)) throw Error('invalid argument: paramsList must be an array');
//the type-checked function
return function(){
for(var i=0,p,arg;p=paramsList[i],arg=arguments[i],i<paramsList.length; i++){
if (typeof p === 'string'){
if (typeof arg !== p) throw new Error('expected type ' + p + ', got ' + typeof arg);
}
else { //function
if (!(arg instanceof p)) throw new Error('expected type ' + String(p).replace(/\s*\{.*/, '') + ', got ' + typeof arg);
}
}
//type checking passed; call the function itself
return f.apply(this, arguments);
};
}
//usage:
var ds = typedFunction([Date, 'string'], function(d, s){
console.log(d.toDateString(), s.substr(0));
});
ds('notadate', 'test');
//Error: expected type function Date(), got string
ds();
//Error: expected type function Date(), got undefined
ds(new Date(), 42);
//Error: expected type string, got number
ds(new Date(), 'success');
//Fri Jun 14 2013 success
它显示了确保参数符合指定类型的通用方法。我很难掌握ds
函数调用中的参数流,回到从typedFunction()
返回的函数。
这就是我的期望:
paramsList
应该参考typedFunction()
&#39> s函数中的第一个参数arguments
应该引用传递给typedFunction
的所有参数的列表,在这种情况下paramsList
和f
。但是,似乎arguments
引用ds
中传递的参数。事情变得模糊的地方。 ds
中提供的参数如何传递给f
? 很抱歉,问题不明确。如果您已经掌握了我想要提出的问题并且可以使问题更容易阅读,请编辑问题。
答案 0 :(得分:2)
为了便于说明,假设我们将返回的函数命名为typeChecker
:
function typedFunction(paramsList, f){
// ...
return function typeChecker() { ... }
}
现在,这里发生了正在发生的事情:
运行
var ds = typedFunction([Date, 'string'], function(d, s){
console.log(d.toDateString(), s.substr(0));
});
在[Date, 'string']
的外部环境(closure)中将paramsList
function(d, s) { ... }
和f
绑定为typeChecker
。这意味着typeChecker
在调用时将通过指定的绑定变量名paramsList
和f
访问此数据。
然后我们运行:
ds(new Date(), 'success');
基本上运行typeChecker(new Date(), 'success')
。
旁注:在任何普通的JS函数中(arrow function表现不同),arguments是一个特殊的类数组对象,在调用函数时提供。该对象包含传递给函数的所有参数,与函数签名中指定的参数数量无关。
这意味着,当我们调用ds(new Date(), 'success')
时,arguments
在概念上看起来像这样:
[dateInstance, 'success']
虽然技术上看起来更像是这样:
{
0: dateInstance,
1: 'success'
}
但这在给定代码中没有区别,因为两个结构都提供了for
循环中使用的数字属性/索引访问。
因此,在typeChecker
内,arg
将引用每个循环迭代arguments
对象中相应索引处的项,即arg=arguments[i]
。
迭代完成后,运行:
return f.apply(this, arguments);
调用最初提供给typedFunction
的函数作为其第二个参数,即f
关闭中绑定到名称typeChecker
的参数,提供{{3 } this
来自typeChecker
,并传递来自typeChecker
的参数。