子函数中的参数对象(适用于chrome控制台,但不适用于其他地方)



我正在做自由代码营的"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的一种特殊模式,在这种模式下,很多你不应该使用的特性都是不允许的。这些功能之一是访问函数的argumentscaller属性,就像您正在使用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";

放到函数或文件的顶部,正如我在上面的代码中所做的。

最新更新