霖澈 發表於 2025-7-8 07:21:00

JavaScript中如何遍历对象?

<h2 id="javascript中如何遍历对象">JavaScript中如何遍历对象?</h2>
<p>今天来点稍微轻松的话题,如何在JavaScript中遍历对象,在平常的工作中,遍历对象是很常见的操作,javascript提供了多种方法来遍历对象的属性。这些方法各有特点,不同的场景需要使用不同的方法。</p>
<p>假设我们有一个<code>Person</code>对象,包含名字和年龄两个属性,下面看看有哪些方式可以遍历这个对象。</p>
<pre><code class="language-js">const person = {
name: 'Philip',
age: 18,
};
</code></pre>
<h2 id="forin">for...in</h2>
<p>遍历对象最基本的方式就是使用<code>for...in</code>,这里需要注意区分和<code>for...of</code>的区别。</p>
<ul>
<li><code>for...in</code> - 遍历可枚举对象,比如<code>Object</code>。</li>
<li><code>for...of</code> - 遍历可迭代对象,比如<code>Array</code>。</li>
</ul>
<p>在以下代码中,<code>key</code>是每个属性的名字 - 对应<code>name</code>和<code>age</code>,而<code>person</code>则是每个属性的值 - 对应<code>Philip</code>和<code>18</code>。</p>
<pre><code class="language-js">for (const key in person) {
console.log(key, person);
}
</code></pre>
<p>输出如下:</p>
<pre><code>name Philip
age 18
</code></pre>
<p><code>for...in</code>是遍历对象最基本的方式,需要注意的是它不仅会遍历对象自身的属性,也会遍历原型链上的属性。假设我们在<code>Object.prototype</code>上添加一个属性,那么这个属性也会被遍历到。</p>
<pre><code class="language-js">Object.prototype.customProperty = 'Hello World';
for (const key in person) {
console.log(key, person);
}
</code></pre>
<p>输出如下:</p>
<pre><code>name Philip
age 18
customProperty Hello World
</code></pre>
<p>如果你只想遍历对象自身的属性,可以使用<code>Object.hasOwnProperty</code>方法来过滤掉原型链上的属性。</p>
<pre><code class="language-js">for (const key in person) {
if (person.hasOwnProperty(key)) {
    console.log(key, person);
}
}
</code></pre>
<h2 id="使用forof--objectkeys">使用<code>for...of</code> + <code>Object.keys</code></h2>
<p><code>Object.keys</code>方法返回一个对象中所有可枚举属性的键名并放到一个数组里,配合<code>for...of</code>可以很方便地遍历对象的属性。</p>
<pre><code class="language-js">for (const key of Object.keys(person)) {
console.log(key, person);
}
</code></pre>
<h2 id="使用forof--objectvalues">使用<code>for...of</code> + <code>Object.values</code></h2>
<p>如果你只关心对象的值,而不在key的话,那么可以使用<code>Object.values</code>方法,它返回一个包含对象所有可枚举属性值的数组。</p>
<pre><code class="language-js">for (const value of Object.values(person)) {
console.log(value);
}
</code></pre>
<p>输出如下:</p>
<pre><code>Philip
18
</code></pre>
<h2 id="forof--objectentries"><code>for...of</code> + <code>Object.entries</code></h2>
<p>下面的方法使用<code>for...of</code>进行遍历,我们都知道<code>for..of</code>是用来遍历可迭代对象的,所以<code>Object.entries</code>返回的一定是一个可迭代对象 - 这里是一个二维数组,然后<code></code>是一个解构操作,负责解构内层一维数组中的值并输出。</p>
<pre><code class="language-js">for (const of Object.entries(person)) {
console.log(key, value);
}
</code></pre>
<p><code>Object.entries(person)</code>输出如下,可以看作是一个键值对组成的二维数组。</p>
<pre><code class="language-js">[, ]
</code></pre>
<p>使用<code></code>进行解构后正好得到两组数据:</p>
<pre><code class="language-js">key = name, value = 'Philip' // 第一组数据
key = age, value = 18 // 第二组数据
</code></pre>
<h2 id="objectentries--foreach"><code>Object.entries</code> + <code>forEach</code></h2>
<p>一个更加函数式的写法是使用数组对象上的<code>forEach</code>方法。</p>
<pre><code class="language-js">Object.entries(person).forEach(() =&gt; {
console.log(key, value);
});
</code></pre>
<p><code>forEach</code>本质上和<code>for...of</code>并无区别,在使用链式操作时,这种方式可读性更好,比如和<code>filter</code>等方法串联调用时。</p>
<pre><code class="language-js">Object.entries(person)
.filter(() =&gt; key !== 'age') // 过滤掉 age 属性
.forEach(() =&gt; console.log(key));
</code></pre>
<p>还有一点要注意,那就是<code>forEach</code>是无法中断的,比如不能使用<code>continue</code>或者<code>break</code>来中断循环,但是<code>for...in</code>和<code>for...of</code>则不受此限制。</p>
<h2 id="reflectownkeys">Reflect.ownKeys</h2>
<p>如果你的对象中有<code>Symbol</code>类型的属性,那么可以使用<code>Reflect.ownKeys</code>方法来获取所有属性的键名。</p>
<pre><code class="language-js">const person = {
name: 'Philip',
age: 18,
: 123,
};

Reflect.ownKeys(person).forEach(key =&gt; {
console.log(key, person);
});
</code></pre>
<p>输出如下:</p>
<pre><code>name Philip
age 18
Symbol(id) 123
</code></pre>
<p><code>Reflect.ownKeys</code>是遍历<code>Symbol</code>类型属性的唯一方法。</p>
<p>最后,如果你使用的是<code>TypeScript</code>,那么所有使用了索引操作的遍历方式(比如<code>person</code>)都需要添加索引签名,否则<code>TypeScript</code>会报错,具体原因可以看这篇:</p>
<p>好了最后用表格总结一下:</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>包含继承属性</th>
<th>包含Symbol</th>
<th>包含不可枚举属性</th>
<th>TypeScript支持</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>for...in</code></td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
<td>需要索引签名</td>
</tr>
<tr>
<td><code>Object.keys()</code></td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td><code>Object.values()</code></td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td><code>Object.entries()</code></td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td><code>Reflect.ownKeys()</code></td>
<td>❌</td>
<td>✅</td>
<td>✅</td>
<td>✅</td>
</tr>
</tbody>
</table>
<p>今天就到这里了,今天是我生日,感谢大家的支持,我们明天见!</p>


</div>
<div id="MySignature" role="contentinfo">
    <div id="ZddSignature">
<div>作者:zdd</div>
<div>出处:http://www.cnblogs.com/graphics/
<div>
<div>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.</div>
</div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/graphics/p/18972113
頁: [1]
查看完整版本: JavaScript中如何遍历对象?