javascript 如何转移“论据”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4775895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:50:44  来源:igfitidea点击:

How to shift "arguments"?

javascriptarrays

提问by mpen

Here's the script:

这是脚本:

function runScripts() {
    if (arguments.length === 0) return;
    chrome.tabs.executeScript(null, {
        file: arguments[0]
    }, function() {
        arguments.shift();
        runScripts.apply(null, arguments);
    });
}

It doesn't work because argumentsis not actually an array, it's just array-like. So how can I "shift" it or hack off the first element so that I can apply this function recursively?

它不起作用,因为arguments它实际上不是一个数组,它只是类似数组。那么我怎样才能“移动”它或砍掉第一个元素,以便我可以递归地应用这个函数呢?

采纳答案by user113716

I assume you want to reference the originalarguments, instead of that from the callback you're passing to chrome.tabs.executeScript.

我假设您想引用原始的arguments,而不是您传递给的回调中的chrome.tabs.executeScript

If so, you'll need to cache it first.

如果是这样,您需要先缓存它。

function runScripts() {
    if (arguments.length === 0) return;
    var args = [];
    Array.prototype.push.apply( args, arguments );

    chrome.tabs.executeScript(null, {
        file: args.shift();
    }, function() {
             // using the modified Array based on the original arguments object
        runScripts.apply(null, args);
    });
}

回答by ClosureCowboy

var params = Array.prototype.slice.call(arguments);
params.shift();

You can check out this blog postwhich explains it in further detail.

您可以查看这篇博客文章,其中更详细地解释了它。

回答by thewildpendulum

[].shift.call(arguments)is also valid. I'm using this in production code and it works as expected.

[].shift.call(arguments)也是有效的。我在生产代码中使用它,它按预期工作。

With this approach, your function becomes a bit more succinct:

使用这种方法,您的函数会变得更加简洁:

function executeScripts() {
    if (arguments.length === 0) return;
    chrome.tabs.executeScript(null, {
        file: [].shift.call(arguments)
    }, function() {
        executeScripts.apply(null, arguments);
    });
}

If you look on MDN, they state that shift()was implemented with this flexibility in mind.

如果您查看 MDN,他们会说shift()实现时考虑到了这种灵活性。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift

回答by Dave Ward

You can transform argumentsinto a regular array like this:

您可以arguments像这样转换为常规数组:

var args = Array.prototype.slice.call(arguments);

回答by Jim Ankrom

Just wanted to point out a potential problem with [].shift.call(arguments).

只是想指出[].shift.call(arguments)的潜在问题。

This seems to have the perhaps unclear intent of shifting your arguments - even for your function's namedparameters - even if used prior to the shift statement.

这似乎具有转移参数的可能不清楚的意图 - 即使对于函数的命名参数 - 即使在 shift 语句之前使用。

For example,

例如,

function testShift (param1, param2) {
    [].shift.call(arguments); 
    if (param1=="ONE") alert("ONE");
}

If you make the following call, what might you expect to happen?

如果您拨打以下电话,您可能期望发生什么?

testShift("ONE", "TWO");

If you expected param1 to stay "ONE", your fix is to set a var to param1 before the shift occurs. It looks like javascript is not binding param1 until the line it is called on - not when the function is called... so modifications to arguments prior to a parameter being used can have unexpected effects.

如果您希望 param1 保持“ONE”,则您的解决方法是在发生转变之前将 var 设置为 param1。看起来 javascript 没有绑定 param1 直到它被调用的那一行 - 而不是在调用函数时......所以在使用参数之前修改参数可能会产生意想不到的效果。

Hopefully now, you'll be able to expect it.

希望现在,您将能够期待它。

回答by gsnedders

You'll need to convert it to an array and then shift. Or, alternatively, drop the first item when converting to an array. Array.prototype.slice.call(arguments, 1)would work for this.

您需要将其转换为数组,然后进行移位。或者,在转换为数组时删除第一项。Array.prototype.slice.call(arguments, 1)会为此工作。

回答by scipilot

In ES6 you can now use Array.from() MDN ref

在 ES6 中,您现在可以使用 Array.from() MDN ref

e.g.

例如

const args = Array.from(arguments);
const str = args.shift();

回答by HappyBambi

Here is an article explains this really well. I copied some key points below. http://www.javascriptkit.com/javatutors/arrayprototypeslice.shtml

这里有一篇文章很好地解释了这一点。我在下面复制了一些要点。 http://www.javascriptkit.com/javatutors/arrayprototypeslice.shtml

For array, remember you can call the slice function to get a sub array.

对于数组,请记住您可以调用 slice 函数来获取子数组。

var abc = [1,2,3,4,5];
abc.slice(0); //[1,2,3,4,5]
abc.slice(1,3); //[2,3]

Since the argument object is only array like, not really an array. The call() / apply() function basically just "borrow" the slice function from Array and use it on the Argument object, and you can even pass parameters into the slice function just as acting on the array.

由于参数对象只是数组,而不是真正的数组。call() / apply() 函数基本上只是从 Array 中“借用” slice 函数并将其用于 Argument 对象,您甚至可以将参数传递到 slice 函数中,就像对数组进行操作一样。

var myobject ={ // array-like collection
    length: 4,
    '0': 'zero',
    '1': 'one',
    '2': 'two',
    '3': 'three'
}

var myarray = Array.prototype.slice.call(myobject) 
// returns myobject as a true array: ["zero", "one", "two", "three"]

var myarray = Array.prototype.slice.call(myobject, 1) 
// returns ["one", "two", "three"]

The one remaining question is why we're calling slice() on the prototype object of Array instead of an array instance. The reason is because this is the most direct route to accessing the slice() method of Array when that's all we're interested in; we could have first created an array instance, but that's less efficient and arguably more abstruse:

剩下的一个问题是为什么我们在 Array 的原型对象而不是数组实例上调用 slice() 。原因是因为这是我们最感兴趣的访问 Array 的 slice() 方法的最直接途径;我们可以先创建一个数组实例,但这效率较低,而且可以说更深奥:

var myarray = new Array().prototype.slice.call(myobject) // less efficient

回答by mpen

In newer versions of JS, we can now write:

在较新版本的 JS 中,我们现在可以编写:

function f(first, ...rest) { ... }

Or

或者

function f() {
    const [first, ...rest] = arguments;
}

Which is a little nicer than "shifting" off the first arg. However, if we did want to, we could first convert argumentsinto a proper array via Array.fromor [...arguments].

这比“转移”第一个 arg 好一点。但是,如果我们确实想要,我们可以首先arguments通过Array.fromor转换为适当的数组[...arguments]

回答by zzzzBov

You could convert the arguments to an actual array and then use that array in the rest of your logic in the function.

您可以将参数转换为实际数组,然后在函数的其余逻辑中使用该数组。

function runScripts()
{
  var i=0, l=arguments.length, arr=[];
  while(i<l)
  {
    arr.push(arguments[i++]);
  }
...rest of your function code

Edit to add: i've had issues with prototypeand callin older versions of IE, so it really depends on what support you'll need.

编辑补充:我已经有问题prototype,并call在旧版本的IE浏览器,所以它实际上取决于什么样的支持,你将需要。