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 循環返回的值都是數據結構的 <strong>鍵值名</strong>。<br>遍歷對象返回的對象的key值,遍歷數組返回的數組的下標(key)。</p></li><li><p>for ... in 循環不僅可以遍歷數字鍵名,還會遍歷原型上的值和手動添加的其他鍵。如——<strong>例3</strong></p></li><li><p>特別情況下, for ... in 循環會以任意的順序遍歷鍵名</p></li></ul><blockquote>總結一句: <strong>for in</strong> 循環特別適合遍歷對象。</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>