我在面向对象的javascript书中做了一些练习,我注意到了这一点:
var a = "hello";
a.charAt('e'); // 'h'
a.charAt('adfadf'); //'h'
为什么对于字符串的charAt()方法,参数中的字符串看似被评估为整数0?
编辑:我知道charAt()的用法通常需要一个整数,并且练习用字符串提供charAt(),我也知道字符串可能会被强制转换为整数,我确认是NaN。感谢肯德尔,建议将这些缺失的信息放在正确的问题中
谢谢!
答案 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
方法时,将采取以下步骤:
- 致电CheckObjectCoercible,将此值作为参数。
- 让 S 成为调用ToString的结果,并将 this 值作为其参数。
- 让位置为ToInteger( pos )。
- 让 size 为 S 中的字符数。
- 如果位置&lt; 0或位置≥大小,返回空字符串。
- 返回长度为1的字符串,其中包含 S 中的一个字符,即位于位置的字符,其中 S <中的第一个(最左侧)字符/ em>被认为是在位置0,下一个在位置1,依此类推。
醇>
第3步是问题的症结所在。 ToInteger
和'e'
'adfadf'
为0
。为什么?再次,到hit the spec的时间:
9.4 ToInteger
抽象操作ToInteger将其参数转换为整数数值。这个抽象操作的功能如下:
我们需要更深入!什么是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方法时,将执行以下步骤:
设S是调用ToString的结果,给它的值为 它的论点。
第3。让位置为ToInteger(pos)。
根据http://ecma262-5.com/ELS5_HTML.htm#Section_9.4
9.4 ToInteger
抽象操作ToInteger将其参数转换为整数数值。这个抽象操作的功能如下:
设number是在输入参数上调用ToNumber的结果。
<强> 2。如果number为NaN,则返回+0。
答案 3 :(得分:2)
charAt()方法以整数作为参数。传递一个字符串将计算为NaN,false,为0.因此,将始终返回字符串中的第一个字符。
答案 4 :(得分:1)
因为charAt
会尝试将您提供的内容转换为数字。将“adfadf”转换为数字会为您提供NaN
或非数字。 charAt
与NaN
的已定义行为是返回第一个字符。
答案 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'));
希望这会对你有所帮助。