Because Number('e')
is NaN
, and <any nonempty string>.charAt(NaN)
just returns the first character. This behavior is exactly what is laid out in the spec:
15.5.4.4 String.prototype.charAt (pos)
When the charAt
method is called with one argument pos, the following steps are taken:
- Call CheckObjectCoercible passing the this value as its argument.
- Let S be the result of calling ToString, giving it the this value as its argument.
- Let position be ToInteger(pos).
- Let size be the number of characters in S.
- If position < 0 or position ≥ size, return the empty String.
- Return a String of length 1, containing one character from S, namely the character at position position, where the first (leftmost) character in S is considered to be at position 0, the next one at position 1, and so on.
Step 3 is the crux of the matter. ToInteger
of both 'e'
and 'adfadf'
is 0
. Why? Again, time to hit the spec:
9.4 ToInteger
The abstract operation ToInteger converts its argument to an integral numeric value. This abstract operation functions as follows:
- Let number be the result of calling ToNumber on the input argument.
- If number is NaN, return +0.
- If number is +0, -0, +∞, or ?∞, return number.
- Return the result of computing sign(number) × floor(abs(number)).
We need to go deeper! What is ToNumber('e'), and what is ToNumber('adfadf')? If you're surprised that I'm once again about to quote the spec, I'm doing something wrong:
9.3.1 ToNumber Applied to the String Type
ToNumber applied to Strings applies the following grammar to the input String. If the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of ToNumber is NaN.
...I'm not going to quote the entire grammar for StringNumericLiteral. Because 'e'
and 'adfadf'
are neither StrDecimalLiteral s nor HexIntegerLiteral s, ToNumber of both of those values is NaN. Finally we have the conversion: from string to NaN
to 0
, which brings us back up the chain to charAt
: position is 0
, so charAt('e')
and charAt('adfadf')
both return the leftmost character in S.
Now, if those strings were instead valid StrNumericLiteral s, such as '0xe'
and '0xadfadf'
:
> 'hello'.charAt('0xe')
""
> 'hello'.charAt('0xadfadf')
""
well, that's a different story for a different answer.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…