【问题标题】:Why does accessing the element next to the given position misbehave, whereas accessing the previous element works correctly? [duplicate]为什么访问给定位置旁边的元素行为异常,而访问前一个元素可以正常工作? [复制]
【发布时间】:2018-09-26 13:09:28
【问题描述】:

给出以下简单的 Javascript 代码:

var a = [ 1, 2, 3 ]

for ( var i in a ) {
    console.log(a[i-1], a[i], a[i+1]);
}

为什么会在下面产生奇怪的输出?

undefined 1 undefined
1 2 undefined
2 3 undefined

第一行的第一个undefined 和最后一行的最后一个undefined 是因为越界访问。但是另外两个undefined 是从哪里来的呢?

【问题讨论】:

  • 这个问题不是其他两个问题的重复。它与隐式转换和迭代数组一样多。 i-1 正常工作而 i+1 不能正常工作的问题与 Javascript 如何选择在混合表达式中进行转换有关,正如我在回答中指出的那样,即使没有数组,您也会遇到类似的问题。

标签: javascript arrays implicit-conversion


【解决方案1】:

一个稍微修改的测试用例很好地暴露了问题:

$ cat test.js 
var a = [ 1, 2, 3 ]

for ( var i in a ) {
    console.log(i-1, i, i+1);
    console.log(a[i-1], a[i], a[i+1]);
    console.log('--------');
}

$ nodejs test.js 
-1 '0' '01'
undefined 1 undefined
--------
0 '1' '11'
1 2 undefined
--------
1 '2' '21'
2 3 undefined
--------

所以,变量i字符串类型。当使用它访问前一个元素时,Javascript 是一种弱类型语言,解释器发现表达式 i-1 只有在将 i 转换为数字时才有意义。为了公平起见(让程序员的生活更有趣),在表达式 i+1 中,解释器将 1 转换为字符串并将 + 视为连接,从而生成数组中缺少的键(或者,如果数组如果足够长,则会访问错误的元素:a[11] 而不是 a[2]a[21] 而不是 a[3],等等)。

在这种特殊情况下,问题来自循环数组的不正确方式(如果您对这个问题的答案不明显,请仔细阅读how to iterate over arrays in JavaScriptexcellent explanation)。但是,在任何其他情况下,如果应该是数字的变量实际上包含一个字符串值(例如,在解析文本数据并忘记进行转换时),它可能会咬你。

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多