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

时间:2012-04-02 17:02:18

标签: javascript

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

var a = "hello";
a.charAt('e'); // 'h'
a.charAt('adfadf'); //'h'

为什么对于字符串的charAt()方法,参数中的字符串看似被评估为整数0?

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

谢谢!

8 个答案:

答案 0 :(得分:11)

因为Number('e')NaN,而<any nonempty string>.charAt(NaN)只返回第一个字符。此行为是exactly what is laid out in the spec

  

15.5.4.4 String.prototype.charAt(pos)

     

当使用一个参数 pos 调用 charAt 方法时,将采取以下步骤:

     
      
  1. 致电CheckObjectCoercible,将值作为参数。
  2.   
  3. S 成为调用ToString的结果,并将 this 值作为其参数。
  4.   
  5. 位置ToInteger pos )。
  6.   
  7. size S 中的字符数。
  8.   
  9. 如果位置&lt; 0或位置≥大小,返回空字符串。
  10.   
  11. 返回长度为1的字符串,其中包含 S 中的一个字符,即位于位置的字符,其中 S <中的第一个(最左侧)字符/ em>被认为是在位置0,下一个在位置1,依此类推。
  12.   

第3步是问题的症结所在。 ToInteger'e' 'adfadf'0。为什么?再次,到hit the spec的时间:

  

9.4 ToInteger

     

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

     
      
  1. number 成为输入参数调用ToNumber的结果。
  2.   
  3. 如果数字 NaN ,请返回 +0
  4.   
  5. 如果数字 + 0 -0 +∞-∞< / strong>,返回数字
  6.   
  7. 返回计算结果sign数字)×floorabs数字))。
  8.   

我们需要更深入!什么是ToNumber('e'),什么是ToNumber('adfadf')?如果你对我再一次quote the spec感到惊讶,我正在做 错误:

  

9.3.1 ToNumber应用于字符串类型

     应用于Strings的

ToNumber将以下语法应用于输入String。如果语法不能将String解释为 StringNumericLiteral 的扩展,则ToNumber的结果为 NaN

...我不打算引用 StringNumericLiteral的整个语法。因为'e''adfadf'既不是 StrDecimalLiteral 也不是 HexIntegerLiteral ,这两个值的ToNumber为 NaN 。最后,我们进行了转换:从字符串到NaN再到0,这会将我们链接到charAt位置0,因此charAt('e')charAt('adfadf')都返回 S 中最左边的字符。

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

> 'hello'.charAt('0xe')
  ""
> 'hello'.charAt('0xadfadf')
  ""

嗯,对于不同的答案,这是一个不同的故事。

答案 1 :(得分:4)

JavaScript核心string.charAt(idx)方法将整数参数作为要返回的字符的索引。

'abc'.charAt(0); // => 'a'

如果你给它一个非整数参数,那么它可能会尝试使用Number(arg)转换器或可能parseInt(arg, 10)将参数转换为数字。如果给定一个不解析为整数的字符串,则这两个函数都返回NaN,因此charAt()函数必须自动将NaN转换为零:

Number('e'); // => NaN
parseInt('e', 10); // => NaN
'abc'.charAt(NaN); // => 'a'

也许是直接相关的,在没有参数的情况下调用charAt()会返回第一个字符:

'abc'.charAt(); // => 'a'

答案 2 :(得分:3)

当你调用String.charAt(pos)时,它首先计算pos的toInteger值,并且因为你给它'e',它的计算结果为0,从而得到你的答案。有关更多信息,请参阅以下内容:


根据http://ecma262-5.com/ELS5_HTML.htm#Section_15.5.4.4

String.prototype.charAt (pos)

返回一个String,其中包含String中位置pos处的字符,该字符串是将此对象转换为String。

如果pos是Number类型的值是一个整数,那么x.charAt(pos)的结果等于x.substring(pos,pos + 1)的结果。

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

  1. 调用CheckObjectCoercible,将此值作为参数传递。
  2. 设S是调用ToString的结果,给它的值为 它的论点。

    第3。让位置为ToInteger(pos)。

  3. 设大小为S中的字符数。
  4. 如果位置&lt; 0或位置≥大小,返回空字符串。
  5. 根据http://ecma262-5.com/ELS5_HTML.htm#Section_9.4

    9.4 ToInteger

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

    1. 设number是在输入参数上调用ToNumber的结果。

      <强> 2。如果number为NaN,则返回+0。

    2. 如果number为+ 0,-0,+∞或-∞,则返回数字。
    3. 返回计算符号(数字)* floor(abs(number))的结果。

答案 3 :(得分:2)

charAt()方法以整数作为参数。传递一个字符串将计算为NaN,false,为0.因此,将始终返回字符串中的第一个字符。

答案 4 :(得分:1)

因为charAt会尝试将您提供的内容转换为数字。将“adfadf”转换为数字会为您提供NaN或非数字。 charAtNaN的已定义行为是返回第一个字符。

答案 5 :(得分:1)

'e'和'adfadf'都是字符串。当作为整数值输入时,字符串总是返回0作为值。

由于“hello”是一个 chars 本身的数组,它会返回第一个索引,即'h'(从0开始)。

答案 6 :(得分:0)

charAt函数将整数而不是字符串作为参数:

"hello".charAt(0) // 'h'
"hello".charAt(1) // 'e'
"hello".charAt(2) // 'l'

当你给它一个字符串时,它基本上最终将它解释为0并返回第一个字符。

答案 7 :(得分:-1)

朋友charAt方法就像

string.charAt(index)

即。你需要将索引传递给方法

如果你想做同样的事情而不是使用像

这样的代码
string.charAt(string.indexOf('a'));

希望这会对你有所帮助。