什么是变量arg在这个函数中引用? Javascript中的参数流

时间:2017-01-15 08:13:00

标签: javascript

这是对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的所有参数的列表,在这种情况下paramsListf。但是,似乎arguments引用ds中传递的参数。事情变得模糊的地方。 ds中提供的参数如何传递给f

您能解释一下事件的逻辑流程/此代码的工作原理吗?

很抱歉,问题不明确。如果您已经掌握了我想要提出的问题并且可以使问题更容易阅读,请编辑问题。

1 个答案:

答案 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在调用时将通过指定的绑定变量名paramsListf访问此数据。

然后我们运行:

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的参数。