Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't ["A","B","C"].map(String.prototype.toLowerCase.call) work?

Tags:

javascript

This, of course, returns what you would expect:

["A","B","C"].map(function (x) {     return x.toLowerCase(); }); // --> ["a", "b", "c"] 

So does using String.prototype.toLowerCase.call:

["A","B","C"].map(function (x) {     return String.prototype.toLowerCase.call(x); }); // --> ["a", "b", "c"] 

It also works if you pass the extra arguments given by map, as it throws away the arguments:

["A","B","C"].map(function (x, index, arr) {     return String.prototype.toLowerCase.call(x, index, arr); }); // --> ["a", "b", "c"] 

But, this does not work:

["A","B","C"].map(String.prototype.toLowerCase.call); // --> TypeError: undefined is not a function 

The following doesn't work either, because arguments has the Object prototype instead of the Array prototype, so slice is undefined on it. Is the reason for the above behavior perhaps because of something like this-- where slice or some other similar Array function is used internally?

["A","B","C"].map(function (x) {     return String.prototype.toLowerCase.apply(x, arguments.slice(1)); }); // --> TypeError: undefined is not a function 
like image 477
Greg Smith Avatar asked Apr 24 '14 22:04

Greg Smith


People also ask

What does toLowerCase do to numbers?

The toLowerCase() method returns the calling string value converted to lower case.

Does toLowerCase mutate the string?

The toLowerCase() method does not change the original string.


2 Answers

Similar Question: Why won't passing `''.trim()` straight to `[].map()`'s callback work?

Map has a optional thisArg which can be used like so:

['A', 'B', 'C'].map(Function.prototype.call, String.prototype.toLowerCase);   // gives ["a", "b", "c"] 
like image 135
Declan Cook Avatar answered Oct 14 '22 01:10

Declan Cook


This is a special behavior of JavaScript's dot-notation.

toLowerCase.call(x) is working because JavaScript uses toLowerCase as this while executing call. This is how call (which is the same Function.prototype.call you find on every function) knows you want it to execute toLowerCase.

Passing call into another function loses that reference, so this no longer refers to toLowerCase.

like image 41
Keen Avatar answered Oct 14 '22 00:10

Keen