为什么javascript的charAt()带有一个字符串返回第一个字母

Nik*_* So 4 javascript

我在面向对象的javascript书中做了一些练习,我注意到这个:

var a = "hello";
a.charAt('e'); // 'h'
a.charAt('adfadf'); //'h'
Run Code Online (Sandbox Code Playgroud)

为什么对于字符串的charAt()方法,参数中的字符串似乎被求值为整数0?

编辑:我知道charAt()的用法通常需要一个整数,并且练习用字符串提供charAt(),我也知道字符串很可能首先被强制转换为整数,我确认是NaN.感谢肯德尔,建议将这些缺失的信息放在正确的问题中

谢谢!

Mat*_*all 11

因为Number('e')NaN,<any nonempty string>.charAt(NaN)只返回第一个字符.这种行为正是规范中列出的内容:

15.5.4.4 String.prototype.charAt(pos)

charAt使用一个参数pos调用该方法时,将执行以下步骤:

  1. 调用CheckObjectCoercible 将此值作为参数传递.
  2. 小号是调用的结果的ToString,给它这个值作为参数.
  3. 位置ToInteger(pos).
  4. 大小S中的字符数.
  5. 如果位置 <0或位置 ≥大小,则返回空字符串.
  6. 返回一个长度为1的字符串,其中包含S中的一个字符,即位置位置的字符,其中S中的第一个(最左边)字符被认为是位置0,下一个字符位于位置1,依此类推.

第3步是问题的关键.ToInteger两个'e''adfadf'0.为什么?再次,时间达到规格:

9.4 ToInteger

抽象操作ToInteger将其参数转换为整数数值.这个抽象操作的功能如下:

  1. number是在输入参数上调用ToNumber的结果.
  2. 如果number为NaN,则返回+0.
  3. 如果number+ 0,-0,+∞-∞,则返回数字.
  4. 返回计算符号(数字floor(abs(number))的结果.

我们需要更深入!什么是ToNumber('e'),什么是ToNumber('adfadf')?如果你很惊讶,我再次都快要引用规范,我在做什么错误:

9.3.1 ToNumber应用于字符串类型

应用于字符串的ToNumber将以下语法应用于输入String.如果语法不能将String解释为StringNumericLiteral的扩展,那么ToNumber的结果是NaN.

...我不打算引用StringNumericLiteral的整个语法.因为'e'并且'adfadf'既不是StrDecimalLiteral也不是HexIntegerLiteral,这两个值的ToNumber都是NaN.最后我们进行了转换:从string到NaNto 0,它将链回到charAt:position0,所以charAt('e')并且charAt('adfadf')都返回S中最左边的字符.

现在,如果这些字符串是有效的StrNumericLiteral,例如'0xe''0xadfadf':

> 'hello'.charAt('0xe')
  ""
> 'hello'.charAt('0xadfadf')
  ""
Run Code Online (Sandbox Code Playgroud)

好吧,对于不同的答案,这是一个不同的故事.

  • 通过ECMA-262规范+1很好的挖掘. (2认同)