[英]Why passing function reference is failing while using function declaration is not?
Following code fails: 以下代码失败:
array.map(String.prototype.toLowerCase)
Throws Uncaught TypeError: String.prototype.toLowerCase called on null or undefined
. 引发
Uncaught TypeError: String.prototype.toLowerCase called on null or undefined
。 Indeed, this
is not set, I got it. 确实,
this
没有设置,我明白了。
But what's weird is that following code returns an array of empty strings without failing: 但是奇怪的是,以下代码返回了一个空字符串数组,但没有失败:
array.map((s) => String.prototype.toLowerCase(s))
Any idea why? 知道为什么吗? Note that I know this is not the way of having an array of lowercased strings.
请注意,我知道这不是使用小写字符串数组的方式。 I'm just wondering why these two approaches behave differently.
我只是想知道为什么这两种方法的行为不同。
In other words, what is the difference between .map(String.prototype.toLowerCase)
and .map((s) => String.prototype.toLowerCase(s))
? 换句话说,
.map(String.prototype.toLowerCase)
和.map((s) => String.prototype.toLowerCase(s))
什么区别? I thought is was identical, but obviously, it behaves differently. 我以为是相同的,但显然,它的行为有所不同。 Note that here,
String.prototype.toLowerCase
could be replaced by anything. 请注意,这里的
String.prototype.toLowerCase
可以替换为任何东西。
What is the difference between
.map(String.prototype.toLowerCase)
and.map((s) => String.prototype.toLowerCase(s))
.map(String.prototype.toLowerCase)
和.map((s) => String.prototype.toLowerCase(s))
之间有什么区别
For the first case when you get the function outside of an object (String.prototype.toLowerCase)
you lose your context, so you context is null and map
tries to call on null or undefined
. 对于第一种情况,当您在对象
(String.prototype.toLowerCase)
之外获取函数时,您会丢失上下文,因此上下文为null,并且map
尝试调用null or undefined
。 With the first solution you can't get the desired result, because you need to pass a context to the toLowerCase
function, which must be each item of the array , but you don't get that each item of array . 对于第一种解决方案,您无法获得理想的结果,因为您需要将上下文传递给
toLowerCase
函数,该函数必须是数组的每个项目 ,但是您不能得到array的每个项目 。
For the second case you need to pass context which is the item
to the String.prototype.toLowerCase
via call
function. 对于第二种情况,您需要通过
call
函数将上下文 (即item
传递给String.prototype.toLowerCase
。
var array = ['ASD', 'BSD']; var lowered = array.map(item => String.prototype.toLowerCase.call(item)); console.log(lowered);
The second approach array.map((s) => String.prototype.toLowerCase(s))
doesn't throw an error, because toLowerCase
isn't taken out of context, ie the method still has String.prototype
as its receiver. 第二种方法
array.map((s) => String.prototype.toLowerCase(s))
不会引发错误,因为toLowerCase
并未脱离上下文,即该方法仍将String.prototype
作为其接收者。
String.prototype.toLowerCase(s))
returns an empty string, because the argument s
is discarded. String.prototype.toLowerCase(s))
返回空字符串,因为参数s
被丢弃。 toLowerCase
takes it value from its receiving object instead. toLowerCase
改为从其接收对象获取它的值。 The receiving object is String.protoype
. 接收对象是
String.protoype
。 To get the actual string the prototype must be converted to string. 为了获得实际的字符串,必须将原型转换为字符串。 This happens with the
String.prototype.toString
method, which evaluates to ""
. 这发生在
String.prototype.toString
方法中,其结果为""
。 Hence String.prototype.toLowerCase(s))
evaluates to ""
. 因此,
String.prototype.toLowerCase(s))
计算结果为""
。
You can verify this behavior by changing the toString
method: 您可以通过更改
toString
方法来验证此行为:
String.prototype.toString = () => "FOO"; console.log(String.prototype.toLowerCase()); // "foo"
The diffrence between .map(String.prototype.toLowerCase) and .map((s) => String.prototype.toLowerCase(s))
is that .map((s) => String.prototype.toLowerCase(s))
takes an arrow function which is an anonymous function. .map(String.prototype.toLowerCase) and .map((s) => String.prototype.toLowerCase(s))
之间的差异在于.map((s) => String.prototype.toLowerCase(s))
需要箭头函数,它是一个匿名函数。 According to definition of arrow function " An arrow function expression has a shorter syntax than a function expression and does not bind its own this, arguments, super, or new.target. " An arrow function does not create its own this, the this value of the enclosing execution context is used. 根据箭头函数的定义“ 箭头函数表达式的语法比函数表达式短,并且不绑定其自身的this,arguments,super或new.target。 ”箭头函数不创建其自身的this,this值。使用封闭执行上下文。 using
.map(String.prototype.toLowerCase)
will not work as you are not passing any execution context to it but it's looking for one to execute. 使用
.map(String.prototype.toLowerCase)
无效,因为您没有向其传递任何执行上下文,而是在寻找要执行的上下文。 For example in the below code 例如下面的代码
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
Please check this link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions 请检查此链接https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
I think I got it finally: 我想我终于明白了:
this
set to undefined
, equivalent to: this
设置为undefined
,等效于: .map((s) => String.prototype.toLowerCase.call(undefined, s))
this
set to String.prototype
, equivalent to: this
设置为String.prototype
,等效于: .map((s) => String.prototype.toLowerCase.call(String.prototype, s))
Now, the question is, why String.prototype.toLowerCase()
is returning an empty string... But this deserves another question :) 现在,问题是,为什么
String.prototype.toLowerCase()
返回一个空字符串...但这值得另一个问题:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.