以下代码失败:
array.map(String.prototype.toLowerCase)
引发Uncaught TypeError: String.prototype.toLowerCase called on null or undefined
。确实,this
未设定,我明白了。
但奇怪的是,以下代码返回一个空字符串数组而不会失败:
array.map((s) => String.prototype.toLowerCase(s))
知道为什么吗? 请注意,我知道这不是使用小写字符串数组的方式。我只是想知道为什么这两种方法的行为不同。
换句话说,.map(String.prototype.toLowerCase)
和.map((s) => String.prototype.toLowerCase(s))
之间有什么区别?我认为是相同的,但很明显,它的表现不同。请注意,String.prototype.toLowerCase
可以替换为任何内容。
答案 0 :(得分:2)
.map(String.prototype.toLowerCase)
和.map((s) => String.prototype.toLowerCase(s))
之间有什么区别?(String.prototype.toLowerCase)
对于第一种情况,当您在对象map
之外获得该函数时,您将丢失上下文,因此您的上下文为空,null or undefined
尝试调用toLowerCase
。使用第一个解决方案,您无法获得所需的结果,因为您需要将上下文传递给item
函数,该函数必须数组中的每个项目,但您不需要#39; t 数组的每个项目。
对于第二种情况,您需要通过String.prototype.toLowerCase
函数将call
传递给上下文。
var array = ['ASD', 'BSD'];
var lowered = array.map(item => String.prototype.toLowerCase.call(item));
console.log(lowered);

答案 1 :(得分:2)
第二种方法array.map((s) => String.prototype.toLowerCase(s))
不会引发错误,因为toLowerCase
不会脱离上下文,即该方法仍有String.prototype
作为其接收方。
String.prototype.toLowerCase(s))
返回一个空字符串,因为参数s
被丢弃。 toLowerCase
从接收对象中获取值。接收对象为String.protoype
。要获取实际字符串,必须将原型转换为字符串。使用String.prototype.toString
方法会发生这种情况,该方法的结果为""
。因此String.prototype.toLowerCase(s))
评估为""
。
您可以通过更改toString
方法验证此行为:
String.prototype.toString = () => "FOO";
console.log(String.prototype.toLowerCase()); // "foo"
答案 2 :(得分:1)
.map(String.prototype.toLowerCase) and .map((s) => String.prototype.toLowerCase(s))
之间的差异是.map((s) => String.prototype.toLowerCase(s))
采用箭头函数,这是一个匿名函数。根据箭头功能的定义
“箭头函数表达式的语法比函数表达式短,并且不绑定它自己的参数,超级或new.target。”
箭头函数不会创建自己的this,使用封闭执行上下文的this值。
使用.map(String.prototype.toLowerCase)
将无法正常工作,因为您没有向其传递任何执行上下文,但它正在寻找一个执行。
例如,在下面的代码中
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
请检查此链接 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
答案 3 :(得分:0)
我想我终于明白了:
this
设置为undefined
,相当于:.map((s) => String.prototype.toLowerCase.call(undefined, s))
this
设置为String.prototype
,相当于:.map((s) => String.prototype.toLowerCase.call(String.prototype, s))
现在,问题是,为什么String.prototype.toLowerCase()
返回一个空字符串...但这值得另一个问题:)