JavaScript在for-in循环中,用点还是中括号?

作者: shisaq 日期: May 23, 2016

初学JS。在用for in循环的时候,对用点还是用中括号产生了困惑。

困惑阐述:

  1. 定义一个对象,含若干属性名称及属性值:
1
2
3
4
5
6
7
8
9
10
11
12
<span style="color: #6ab825; font-weight: bold;">var</span> <span style="color: #d0d0d0;">bio</span> <span style="color: #d0d0d0;">=</span> <span style="color: #d0d0d0;">{</span>
  <span style="color: #ed9d13;">"name"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"shisaq lee"</span><span style="color: #d0d0d0;">,</span>
  <span style="color: #ed9d13;">"role"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"Front-end Developer"</span><span style="color: #d0d0d0;">,</span>
  <span style="color: #ed9d13;">"contacts"</span><span style="color: #d0d0d0;">:</span> <span style="color: #d0d0d0;">{</span>
    <span style="color: #ed9d13;">"mobile"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"123-456-7890"</span><span style="color: #d0d0d0;">,</span>
    <span style="color: #ed9d13;">"email"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"123@gmail.com"</span><span style="color: #d0d0d0;">,</span>
    <span style="color: #ed9d13;">"twitter"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"@123"</span><span style="color: #d0d0d0;">,</span>
    <span style="color: #ed9d13;">"github"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"1234"</span><span style="color: #d0d0d0;">,</span>
    <span style="color: #ed9d13;">"blog"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"123.com"</span><span style="color: #d0d0d0;">,</span>
    <span style="color: #ed9d13;">"location"</span><span style="color: #d0d0d0;">:</span> <span style="color: #ed9d13;">"Pittsburgh, PA, USA"</span>
  <span style="color: #d0d0d0;">}</span>
<span style="color: #d0d0d0;">}</span>
  1. for in 循环遍历此对象的名称及属性值:

    for (contact in bio.contacts) { if (bio.contacts.hasOwnProperty(contact)) { console.log(contact); console.log(bio.contacts.contact); } }

  2. 猜输出结果是什么?

这就是困扰我的问题, bio.contacts.contact 没有被定义,所以没有正常输出。

思考contact代表的是bio.contacts这个对象里每个属性的名称。当 for in 循环遍历到第1个时,contact代表的是mobile不,其实是"mobile"。因此,当代码进行到 console.log(bio.contacts.contact); 的时候,其实对应的是 console.log(bio.contacts."mobile"); 。但因其带有双引号,所以这时候用 . 是取不到mobile的值的。此时要想取mobile的值,就是用另一种方法的时候了。

for in 循环中的问题代码微调一下:

1
2
3
4
5
6
  <span style="color: #6ab825; font-weight: bold;">for</span> <span style="color: #d0d0d0;">(contact</span> <span style="color: #6ab825; font-weight: bold;">in</span> <span style="color: #d0d0d0;">bio.contacts)</span> <span style="color: #d0d0d0;">{</span>
    <span style="color: #6ab825; font-weight: bold;">if</span> <span style="color: #d0d0d0;">(bio.contacts.hasOwnProperty(contact))</span> <span style="color: #d0d0d0;">{</span>
      <span style="color: #d0d0d0;">console.log(contact);</span>
      <span style="color: #d0d0d0;">console.log(bio.contacts<span style="color: #ff0000;">[</span>contact<span style="color: #ff0000;">]</span>);</span>
    <span style="color: #d0d0d0;">}</span>
  <span style="color: #d0d0d0;">}</span>

我仅把 . 换成了  [ ]

此时重新运行代码,结果如下:

看到正确结果,此时我的内心是激动的😄😄

当时改完,自己还挺不理解,[ ] 不是用在数组中的么?怎么能用在对象中呢?

在JavaScript里,有2种方法显示对象中某个属性的值:

  1. 对象.属性 === 该属性的值,用本文例子就是:bio.contacts.mobile === "123-456-7890"

  2. 对象[“属性”] === 该属性的值。用本文例子就是:bio.contacts["mobile"] === "123-456-7890"

关于以上两种方法的区别,请参考如下这篇文章:http://www.dev-archive.net/articles/js-dot-notation/。虽然是英文,但是不长,总结起来就是:

  1. . 速度更快,阅读也更容易;

  2. [ ] 可以允许含有特殊字符的属性名称。

结合到本文我就明白了,我在循环中犯了一个错误,contact代表的是"mobile" 而不是mobile。双引号当然是特殊字符,所以这里我只能用 [ ] ,而不能用 . 来获取mobile的值了。同时用中括号,仍然是对对象进行操作,并没有对数组进行操作。

换言之,在 for in 循环中,选取属性名称和属性值的时候一定要谨慎。若for in 的目标是一个对象而不是一个数组,那就只能用中括号了。换言之,如果要操作一个数组,其实是有更好的方法的: for循环 或 forEach循环 。参见:Udacity关于for-in循环的参考指南。并且,在火狐MDN关于for in的例子中,也用的是中括号,参见这里:Mozila Developer Network for…in(中文版)。

如果对这两种表示方法感兴趣,可以读一读如下文章:

1
2
3
4
5
6
7
1. <a href="http://stackoverflow.com/questions/4968406/javascript-property-access-dot-notation-vs-brackets" class="question-hyperlink">JavaScript property access: dot notation vs. brackets?
</a>




2. <a href="https://medium.com/@prufrock123/js-dot-notation-vs-bracket-notation-797c4e34f01d#.kp9uzdmao">JS dot-notation vs. bracket notation</a>