如何通过Function.prototype.apply()更改调用函数的参数?

时间:2023-01-31 18:36:08
function foo1(a,b){
   console.log(arguments); //["oldValue","oldValue"]

   var newArguments = foo2.apply(this,arguments);
   for (var i=0;i<arguments.length;i++){
      arguments[i] = newArguments[i];   
}
   console.log(arguments); //["newValue","newValue"]
}

function foo2(){
   arguments[0] = "newValue";
   arguments[1] = "newValue";
   console.log(arguments); //["newValue","newValue"]
   return arguments;
}

foo1("oldValue","oldValue");

I'd like to change foo1 arguments values by outer function foo2. I did it by returning array with new arguments in foo2 and replacing foo1 arguments with returned array in foo1. Is there any other - more elegant - way to do so?

我想通过外部函数foo2更改foo1参数值。我通过在foo2中使用新参数返回数组并用foo1中的返回数组替换foo1参数来完成它。有没有其他更优雅的方式呢?

3 个解决方案

#1


0  

https://jsbin.com/jibodu/1/edit?js,console

If you're returning the two new arguments from foo2 just set the arguments to that return value:

如果你从foo2返回两个新参数,只需将参数设置为该返回值:

arguments = foo2();

full code:

function foo1(a,b){
   console.log(arguments); //["oldValue","oldValue"]
    arguments = foo2();
   var newArguments = foo2.apply(this,arguments);
   for (var i=0;i<arguments.length;i++){
      arguments[i] = newArguments[i];   
}
   console.log(arguments); //["newValue","newValue"]
}

#2


0  

Why don't you receive the arguments directly?

你为什么不直接收到这些论据?

function foo1() {
  console.log('foo1', arguments); // foo1 { '0': 'oldValue', '1': 'oldValue' }

  arguments = foo2.apply(this, arguments); 

  console.log('foo1', arguments); // foo1 { '0': 'newValue', '1': 'newValue' }

}

function foo2() {
  arguments[0] = 'newValue';
  arguments[1] = 'newValue';
  console.log('foo2', arguments); // foo2 { '0': 'newValue', '1': 'newValue' }
  return arguments;
}

foo1('oldValue', 'oldValue');


Update 1

Since you want to change a, b also, I would try calling foo1 "again" like below:

既然你想改变a,b,我会尝试再次调用foo1,如下所示:

function foo1(a, b) {
  console.log('foo1', arguments);

  if (a === 'oldValue') // Detect if `arguments` has been changed or not. 
                        // (You can also use a variable to record the change if you prefer.)
    // If not, change the arguments and call `foo1` using the new arguments
    return foo1.apply(this, foo2.apply(this, arguments));

  console.log('foo1 (after changed)', arguments , a, b);
  // Do something you want to do originally in `foo1`
}

I suppose that you can make a new function instead of change the arguments inside the foo1, since it seems a little tricky to me?

我想你可以创建一个新函数而不是改变foo1中的参数,因为它对我来说似乎有点棘手?

#3


0  

ok I found resolution. I've just changed first parameter in apply() to "arguments". Now it refers to arguments of caller function and by 'this' I can directly change its values. nonetheless thanks for support!

好的,我找到了决心。我刚刚将apply()中的第一个参数更改为“arguments”。现在它引用了调用函数的参数,并且通过'this'我可以直接改变它的值。尽管如此,感谢您的支持!

function foo1(a, b) {
   foo2.apply(arguments,arguments);
   console.log(arguments);  //["newValue","newValue"]
   console.log(a); //"newValue"
}
function foo2() {
   this[0] = "newValue";
   this[1] = "newValue";
};
foo1("oldValue","oldValue");

#1


0  

https://jsbin.com/jibodu/1/edit?js,console

If you're returning the two new arguments from foo2 just set the arguments to that return value:

如果你从foo2返回两个新参数,只需将参数设置为该返回值:

arguments = foo2();

full code:

function foo1(a,b){
   console.log(arguments); //["oldValue","oldValue"]
    arguments = foo2();
   var newArguments = foo2.apply(this,arguments);
   for (var i=0;i<arguments.length;i++){
      arguments[i] = newArguments[i];   
}
   console.log(arguments); //["newValue","newValue"]
}

#2


0  

Why don't you receive the arguments directly?

你为什么不直接收到这些论据?

function foo1() {
  console.log('foo1', arguments); // foo1 { '0': 'oldValue', '1': 'oldValue' }

  arguments = foo2.apply(this, arguments); 

  console.log('foo1', arguments); // foo1 { '0': 'newValue', '1': 'newValue' }

}

function foo2() {
  arguments[0] = 'newValue';
  arguments[1] = 'newValue';
  console.log('foo2', arguments); // foo2 { '0': 'newValue', '1': 'newValue' }
  return arguments;
}

foo1('oldValue', 'oldValue');


Update 1

Since you want to change a, b also, I would try calling foo1 "again" like below:

既然你想改变a,b,我会尝试再次调用foo1,如下所示:

function foo1(a, b) {
  console.log('foo1', arguments);

  if (a === 'oldValue') // Detect if `arguments` has been changed or not. 
                        // (You can also use a variable to record the change if you prefer.)
    // If not, change the arguments and call `foo1` using the new arguments
    return foo1.apply(this, foo2.apply(this, arguments));

  console.log('foo1 (after changed)', arguments , a, b);
  // Do something you want to do originally in `foo1`
}

I suppose that you can make a new function instead of change the arguments inside the foo1, since it seems a little tricky to me?

我想你可以创建一个新函数而不是改变foo1中的参数,因为它对我来说似乎有点棘手?

#3


0  

ok I found resolution. I've just changed first parameter in apply() to "arguments". Now it refers to arguments of caller function and by 'this' I can directly change its values. nonetheless thanks for support!

好的,我找到了决心。我刚刚将apply()中的第一个参数更改为“arguments”。现在它引用了调用函数的参数,并且通过'this'我可以直接改变它的值。尽管如此,感谢您的支持!

function foo1(a, b) {
   foo2.apply(arguments,arguments);
   console.log(arguments);  //["newValue","newValue"]
   console.log(a); //"newValue"
}
function foo2() {
   this[0] = "newValue";
   this[1] = "newValue";
};
foo1("oldValue","oldValue");