我正在做自由代码营的"Seek and Destroy"练习。第一个参数之后的任何参数都应该从数组中过滤出来。
我想出了这个代码,在chrome控制台工作:
function destroyer(arr) {
return arr.filter(function(x){
for(var i = 1; i < destroyer.arguments.length; i++){
if(x == destroyer.arguments[i]) {return false;}
}
return true;
});
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3); //should return [1, 1]
在JS Bin和其他地方,它不做任何事情。只有当我将console.log与一个新数组一起使用而不是只返回时,它才会工作。当我在Free Code Camp中运行它时,我得到:
TypeError: 'caller'和'arguments'是受限的函数属性并且不能在此上下文中访问。
我发现这可能与严格模式有关。但它到底是什么意思呢?这是不是说我不能在子函数中使用父函数的参数对象?
如果我先将参数转换成数组,然后在子函数中使用该数组,我可以使它在任何地方工作。但我很好奇为什么在子函数中的参数确实在chrome控制台工作,但不在其他地方,以及是否有一种方法可以在子函数中使用参数对象。严格模式是JavaScript的一种特殊模式,在这种模式下,很多你不应该使用的特性都是不允许的。这些功能之一是访问函数的arguments
或caller
属性,就像您正在使用destroyer.arguments
一样,这就是为什么当您试图在严格模式下执行此操作时会出现错误。
arguments
作为外部函数中的一个特殊变量访问,并将其赋值给一个变量:
// use strict mode
"use strict";
function destroyer(arr) {
// assign arguments to a variable that can be accessed by the inner
// function
var destroyerArguments = arguments;
return arr.filter(function(x){
// use destroyerArguments instead of destroyer.arguments
for(var i = 1; i < destroyerArguments.length; i++){
if(x == destroyerArguments[i]) {return false;}
}
return true;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3)); // prints [ 1, 1 ]
请注意,默认严格模式是不启用的,所以当你在Chrome的控制台上运行你的代码,这些功能是不允许的。但是,Free Code Camp可能会自动启用严格模式,因此您必须相应地设计代码。您可以通过添加
行来启用严格模式"use strict";
放到函数或文件的顶部,正如我在上面的代码中所做的。