如何改变“论点”?

时间:2011-01-23 19:23:19

标签: javascript arrays

这是脚本:

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

它不起作用,因为arguments实际上不是一个数组,它只是数组。那么我如何“移动”它或者破解第一个元素,以便我可以递归地应用这个函数呢?

11 个答案:

答案 0 :(得分:33)

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

您可以查看此blog post,以便进一步详细说明。

答案 1 :(得分:23)

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

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

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);
    });
}

答案 2 :(得分:10)

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

通过这种方法,您的功能变得更加简洁:

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

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

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

答案 3 :(得分:6)

您可以将arguments转换为常规数组,如下所示:

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

答案 4 :(得分:5)

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

这似乎有可能不明确的意图改变你的论点 - 即使你的函数的命名的参数 - 即使在shift语句之前使用。

例如,

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

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

testShift("ONE", "TWO");

如果您希望param1保持" ONE",您的修复是在转换发生之前将var设置为param1。看起来javascript没有绑定param1,直到它被调用的行 - 而不是在调用函数时...所以在使用参数之前修改参数会产生意想不到的效果。

希望现在,你能够期待它。

答案 5 :(得分:3)

您需要将其转换为数组然后转换。或者,或者,在转换为数组时删除第一个项目。 Array.prototype.slice.call(arguments, 1)可以为此工作。

答案 6 :(得分:2)

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

e.g。

APP_STL := c++_shared
APP_ABI := armeabi-v7a
NDK_TOOLCHAIN_VERSION := clang

答案 7 :(得分:1)

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

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

编辑添加:我在旧版本的IE中遇到了prototypecall的问题,所以这实际上取决于您需要什么样的支持。

答案 8 :(得分:1)

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

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

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

由于参数对象只是数组,而不是数组。 call()/ apply()函数基本上只是&#34;借用&#34;来自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"]

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

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

答案 9 :(得分:1)

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

export default class Tealium {
    static initialize(
        account: string,
        profile: string,
        environment: string,
        iosDatasource: string,
        androidDatasource: string,
        overrideCollectDispatchUrl: string,
        janusID: string,
        invitationCode: string,
        instanceName: string = "MAIN",
        isLifecycleEnabled: boolean = true,
    ): any {
        if (Platform.OS !== "ios") {
            return
        }

        TealiumModule.initialize(
            account,
            profile,
            environment,
            iosDatasource,
            androidDatasource,
            overrideCollectDispatchUrl,
            janusID,
            invitationCode,
            instanceName,
            isLifecycleEnabled,
        )
    }

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

这比“转移”第一个arg更好。但是,如果确实愿意,我们可以先通过function f() { const [first, ...rest] = arguments; } argumentsArray.from转换为适当的数组。

答案 10 :(得分:0)

我接受了这个:

function executeScripts() {
    if (arguments.length === 0) return;
    var args = Array.prototype.slice.call(arguments);
    chrome.tabs.executeScript(null, {
        file: args.shift()
    }, function() {
        executeScripts.apply(null, args);
    });
}

在撰写Google Chrome扩展程序时非常有用。我想在我的内容脚本中使用jQuery,但是你必须先加载它。通过链接chrome.tabs.executeScript来调用你可以做到这一点:

chrome.browserAction.onClicked.addListener(function(tab) {
    executeScripts('jquery-1.4.4.min.js', 'content.js');
});