javascript - 为什么当省略参数时,修改函数参数数组的方法会失败?

标签 javascript function arguments

我正在使用“劫持”修改一些“核心”JS软件的几个功能:

var orig_func = func; // initially function(a,b,c,d)

func = function(a,b,c,d) {
    // modify arguments
    d = someCustomization(c,d);
    // do additional stuff
    doSomethingCustom(a);
    // apply the original "core" function
    return orig_func.apply(this,arguments);
}

效果很好除非修改的参数是可选的:调用

func(a,b);

d未定义的方式工作,即使someCustomization 在其两个参数均为未定义时返回其他内容>.

这是一个在 cosole 中使用的 MVCE:

var f = function(optionalParam){ if(optionalParam) console.log(optionalParam); };
var orig_f = f;
f = function(optionalParam){
    optionalParam = optionalParam ? 'custom: '+optionalParam : 'default';
    orig_f.apply(this, arguments);
};
f(); // shows undefined
f('test'); // shows 'custom: test'

“预期”行为是在第一种情况下在控制台中看到“default”,但我得到的是undefined

经过一些实验并使用 this thread我总结了在 corresponding answer 中添加定位参数我在 MCVE 方面提出了以下解决方案:

var f = function(some,optionalParam){
    console.log('some:',some);
    console.log('optionalParam:',optionalParam);
};
var orig_f = f;
f = function(some,optionalParam){
    if(optionalParam)
        optionalParam = 'custom: '+optionalParam;
    else {
        var argPosition = 2;
        while(arguments.length < argPosition)
            [].push.call(arguments,undefined);
        arguments[argPosition-1] = 'default';
    }
    orig_f.apply(this, arguments);
};
f(); // shows 'some: undefined' and 'optionalParam: default'

或者就初始任务而言:

var orig_func = func; // initially function(a,b,c,d)

func = function(a,b,c,d) {
    // modify arguments
    while(arguments.length < 4)
        [].push.call(arguments,undefined);
    arguments[3] = someCustomization(c,d);
    // do additional stuff
    doSomethingCustom(a);
    // apply the original "core" function
    return orig_func.apply(this,arguments);
}

但是我真的无法解释第一种方法的问题是什么:为什么它对必需(已使用)参数有效,而对可选(未使用)参数却失败?和闭店有什么关系吗?为什么在第二种情况下darguments“没有连接”?

最佳答案

参数“魔术绑定(bind)”是通过迭代实际参数创建的,因此如果参数不存在,则不会创建绑定(bind):

function a(x, y) {
    y = 42;
    console.log(arguments)
}

a(10, 20)
a(10)

也就是说,使用魔法绑定(bind)是一个坏主意,而且它们无论如何都无法在严格模式下工作。如果事先知道参数的数量,只需执行

orig_func.call(this, a, b, c, d);

否则使用 splat ...args 并对其进行操作。

关于javascript - 为什么当省略参数时,修改函数参数数组的方法会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49340634/

相关文章:

perl - 我可以引用带有一些参数的命名子例程吗

javascript - 如何使用 javascript 恢复模糊背景(使用 jquery 隐藏)

python - 如何从函数值中提取特定列?

c - 函数内的函数不起作用

scala - 如何做非专门类型有接受 Function1 的方法?

arguments - 为什么这个没有参数的 TCL proc 不起作用?

java - java中如何使用参数和实参?

javascript - 非侵入性的javascript性能代理?

javascript - 如何从异步调用返回响应?

javascript - 使用 deepWithDataAndEvents = true 克隆的可拖动无法再次拖动