js 基础 for in 和 for of的区别详解

for in 和 for of 相对于大家肯定都不陌生,都是用来遍历属性的没错。那么先看下面的一个例子:

例1

    const obj = {
        a: 1,
        b: 2,
        c: 3
    }
    for (let i in obj) {
        console.log(i)
        // a
        // b
        // c
    }
    for (let i of obj) {
        console.log(i)
        // Uncaught TypeError: obj is not iterable 报错了
    }

以上代码通过 for in 和 for of 对一个obj对象进行遍历,for in 正常的获取了对象的 key值,分别打印 a、b、c,而 for of却报错了。


例2:

以上是遍历对象,下面再看一个遍历数组的例子。

    const arr = ['a', 'b', 'c']
    // for in 循环
    for (let i in arr) {
        console.log(i)
        // 0
        // 1
        // 2
    }
<span class="hljs-comment">// for of</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">of</span> arr) {
    <span class="hljs-built_in">console</span>.log(i)
    <span class="hljs-comment">// a</span>
    <span class="hljs-comment">// b</span>
    <span class="hljs-comment">// c</span>
}</code></pre><p>以上代码是对一个数组进行遍历, for in 返回的值为 0、1、2,这不是数组的下标吗? 而 for of 返回的是 a、b、c,这一次没有报错,为什么呢?</p><p><br></p><h4 id="例3">例3</h4><pre><code class="hljs javascript">    <span class="hljs-keyword">const</span> arr = [<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>]
<span class="hljs-comment">// 手动给 arr数组添加一个属性</span>
arr.name = <span class="hljs-string">'qiqingfu'</span>

<span class="hljs-comment">// for in 循环可以遍历出 name 这个键名</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> arr) {
    <span class="hljs-built_in">console</span>.log(i)
    <span class="hljs-comment">// a</span>
    <span class="hljs-comment">// b</span>
    <span class="hljs-comment">// name</span>
}</code></pre><h4 id="for-in-的特点"><br></h4><h2>for in 的特点</h2><p>结合上面的两个例子,分析得出:</p><ul><li><p>for ... in 循环返回的值都是数据结构的&nbsp;<strong>键值名</strong>。<br>遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。</p></li><li><p>for ... in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。如——<strong>例3</strong></p></li><li><p>特别情况下, for ... in 循环会以任意的顺序遍历键名</p></li></ul><blockquote>总结一句:&nbsp;<strong>for in</strong>&nbsp;循环特别适合遍历对象。</blockquote><p><br></p><h2>for of 特点</h2><ul><li><p>for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名</p></li><li><p>一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。</p><p>例1这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable</p></li><li><p>for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。</p></li><li><p>提供了遍历所有数据结构的统一接口</p></li></ul><p><br></p><h4 id="哪些数据结构部署了-symbol.iteratoer属性了呢">哪些数据结构部署了 Symbol.iteratoer属性了呢?</h4><p>只要有 iterator 接口的数据结构,都可以使用 for of循环。</p><ul><li>数组 Array</li><li>Map</li><li>Set</li><li>String</li><li>arguments对象</li><li>Nodelist对象, 就是获取的dom列表集合</li></ul><p>以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(...)、和解构赋值等操作。</p><p>我也想让对象可以使用 for of循环怎么办?使用 Object.keys() 获取对象的 key值集合后,再使用 for of</p><p>以例1为例</p><pre><code class="hljs javascript">    <span class="hljs-keyword">const</span> obj = {
    <span class="hljs-attr">a</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">b</span>: <span class="hljs-number">2</span>,
    <span class="hljs-attr">c</span>: <span class="hljs-number">3</span>
}

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">of</span> <span class="hljs-built_in">Object</span>.keys(obj)) {
    <span class="hljs-built_in">console</span>.log(i)
    <span class="hljs-comment">// 1</span>
    <span class="hljs-comment">// 2</span>
    <span class="hljs-comment">// 3</span>
}</code></pre><p>也可以给一个对象部署 Symbol.iterator属性。</p><p><br></p><p>来源:https://www.cnblogs.com/qiqingfu/archive/2018/11/28/10035554.html</p><p><br></p></div>
posted @ 2019-06-20 14:51  奋斗的中年人哈哈哈  阅读(7141)  评论(1编辑  收藏  举报