最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript map array with 'fromCharCode' (character length) - Stack Overflow

programmeradmin6浏览0评论

The following is from an interactive session in the Chrome console:

myarray
//-> [67, 65, 84]

String.fromCharCode(67)
//-> "C"

String.fromCharCode(67).length
//-> 1

String.fromCharCode(myarray[0])
//-> "C"

String.fromCharCode(myarray[0]).length
//-> 1

myarray.map(String.fromCharCode)
//-> ["C", "A", "T"]

myarray.map(String.fromCharCode)[0]
//-> "C"

myarray.map(String.fromCharCode)[0].length
//-> 3

Can anyone explain why the last operation returns 3?

The following is from an interactive session in the Chrome console:

myarray
//-> [67, 65, 84]

String.fromCharCode(67)
//-> "C"

String.fromCharCode(67).length
//-> 1

String.fromCharCode(myarray[0])
//-> "C"

String.fromCharCode(myarray[0]).length
//-> 1

myarray.map(String.fromCharCode)
//-> ["C", "A", "T"]

myarray.map(String.fromCharCode)[0]
//-> "C"

myarray.map(String.fromCharCode)[0].length
//-> 3

Can anyone explain why the last operation returns 3?

Share Improve this question edited Apr 6, 2011 at 15:22 Andy E 345k86 gold badges480 silver badges450 bronze badges asked Apr 6, 2011 at 13:13 David WallisDavid Wallis 5624 silver badges11 bronze badges 2
  • Firefox 4 also says "3" (fiddle) – Pointy Commented Apr 6, 2011 at 13:27
  • @T.J. Crowder The presentation does lack some explanatory support but, though I was dubious at first, I'm hooked :-) – Pointy Commented Apr 6, 2011 at 13:28
Add a ment  | 

3 Answers 3

Reset to default 17

Very interesting question.

And the answer is: The reason you're getting 3 at the end is that fromCharCode returns a string with as many characters as there are arguments in the call to it, and map calls the callback function with three arguments: The value of the element, the index of the element, and the object being traversed. Thus, a string with three characters, but not three readily-displayed characters. Tricky.

Specifically, we get "C" for the first argument; character 0 for the second argument (since we're looking at [0]; it would be 1 for [1], etc.), and a character based on coercing the array into a number (using whatever rules fromCharCode uses for that; Šime Vidas says below that it'll do ToUInt16 on it, which will result in 0).

So, for instance:

> String.fromCharCode(67, 0, [67, 65, 84]).length
3

...just as with the call from map.

For clarity:

> String.fromCharCode(67, 0, [67, 65, 84]).length
3
> String.fromCharCode(67, 0, null).length
3
> String.fromCharCode(67, 0, 0, 0, 0, 0, 0).length
7

If we ensure we only pass it the one argument at a time, we don't see that unexpected effect, so while using it directly gives us a result I think most of us wouldn't expect:

> [67, 65, 84].map(String.fromCharCode)
["C", "A", "T"]
> [67, 65, 84].map(String.fromCharCode)[0]
"C"
> [67, 65, 84].map(String.fromCharCode)[0].length
3

...this gives us a more easily-understood result:

> [67, 65, 84].map(function(value) { return String.fromCharCode(value); })
["C", "A", "T"]
> [67, 65, 84].map(function(value) { return String.fromCharCode(value); })[0]
"C"
> [67, 65, 84].map(function(value) { return String.fromCharCode(value); })[0].length
1

I can't expand much on T.J. Crowder's great answer, but I can provide a workaround for this specific problem.

Rather than

myarray.map(String.fromCharCode);

Use

String.fromCharCode.apply(String, myarray).split("");

Aside from the benefit of returning the expected result, this also works without relying on the ECMAScript 5th Edition method, Array.prototype.map, thus making it more patible.

Ran into the same problem and found this thread. If you're into ES6, I propose this solution:

arr.map((c)=>String.fromCharCode(c));
发布评论

评论列表(0)

  1. 暂无评论