这是脚本:
function runScripts() {
if (arguments.length === 0) return;
chrome.tabs.executeScript(null, {
file: arguments[0]
}, function() {
arguments.shift();
runScripts.apply(null, arguments);
});
}
它不起作用,因为arguments
实际上不是一个数组,它只是数组。那么我如何“移动”它或者破解第一个元素,以便我可以递归地应用这个函数呢?
答案 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中遇到了prototype
和call
的问题,所以这实际上取决于您需要什么样的支持。
答案 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;
}
或arguments
将Array.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');
});