独立的人 發表於 2020-8-27 08:20:00

javascript遍历对象的几种方法

<p>总结下在JavaScript中遍历对象的几种方法。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">for in</span></p>
<p>for in循环是最基础的遍历对象的方式,除了能拿到到对象自身的属性之外,它还能拿到对象原型链上的属性。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个对象并指定其原型,yanggb为原型上的属性</span>
const obj =<span style="color: rgba(0, 0, 0, 1)"> Object.create({
yanggb: </span>'yanggb'<span style="color: rgba(0, 0, 0, 1)">
})

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1为对象自身的属性</span>
obj.yanggb1 = 'yanggb1'

<span style="color: rgba(0, 0, 255, 1)">for</span> (let key <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> obj) {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1, yanggb</span>
}</pre>
</div>
<p>可以看到对象原型上的属性也被循环出来了,首先是遍历了自身的属性,然后逐层往上遍历原型链上原型的属性。</p>
<p>如果想要过滤掉原型链上的属性,也可以使用对象的hasOwnProperty()方法判断其是否是自身属性,以此来达到只针对自身的属性做相应操作的目的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">for</span> (let key <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> obj) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (obj.hasOwnProperty(key)) {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<p>这时候原型上的yanggb属性就被过滤掉了。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">Object.keys</span></p>
<p>Object.keys()是ES5新增的一个对象方法,该方法返回对象自身属性名组成的数组,它会自动过滤掉原型链上的属性,然后可以通过数组的forEach()方法来遍历。</p>
<div class="cnblogs_code">
<pre>Object.keys(obj).forEach((key) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1</span>
})</pre>
</div>
<p>此外还有Object.values()方法和Object.entries()方法,这两方法的作用范围和Object.keys()方法类似,分别是取得对象的属性值数组和属性键值数组数组。</p>
<p>for in循环和Object.keys()方法一样,都不会返回对象的不可枚举属性,如果需要遍历不可枚举的属性,就要使用Object.getOwnPropertyNames()方法了。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">Object.getOwnPropertyNames<strong><br></strong></span></p>
<p>Object.getOwnPropertyNames()同样也是ES5新增的一个对象方法,该方法会返回对象自身属性名组成的数组,包括不可枚举的属性,因此也可以通过数组的forEach()方法来遍历。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个对象并指定其原型,yanggb为原型上的属性</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1为对象自身的属性并且不可枚举</span>
const obj =<span style="color: rgba(0, 0, 0, 1)"> Object.create({
yanggb: </span>'yanggb'<span style="color: rgba(0, 0, 0, 1)">
}, {
yanggb1: {
value: </span>'yanggb1'<span style="color: rgba(0, 0, 0, 1)">,
enumerable: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
}
})

obj.yanggb2 </span>= 'yanggb2'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 不包括不可枚举的yanggb1属性</span>
Object.keys(obj).forEach((key) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1</span>
<span style="color: rgba(0, 0, 0, 1)">})

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 包括不可枚举的yanggb1属性</span>
Object.getOwnPropertyNames(obj).forEach((key) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb1,yanggb2</span>
})</pre>
</div>
<p>而在ES2015新增了Symbol数据类型,该类型可以作为对象的键。针对该类型,ES2015同样新增了一个Object.getOwnPropertySymbols()方法。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">Object.getOwnPropertySymbols<strong><br></strong></span></p>
<p>Object.getOwnPropertySymbols()方法返回对象自身的Symbol属性组成的数组,不包括字符串属性等其他属性。</p>
<div class="cnblogs_code">
<pre>Object.getOwnPropertySymbols(obj).forEach((key) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj)
})</span></pre>
</div>
<p>此时什么都没有输出,因为该对象还没有Symbol属性。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 给对象添加一个不可枚举的Symbol属性</span>
<span style="color: rgba(0, 0, 0, 1)">Object.defineProperties(obj, {
: {
value: </span>'Symbol yanggb'<span style="color: rgba(0, 0, 0, 1)">,
enumerable: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
}
})

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 给对象添加一个可枚举的Symbol属性</span>
obj = 'Symbol yanggb1'<span style="color: rgba(0, 0, 0, 1)">

Object.getOwnPropertySymbols(obj).forEach((key) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Symbol yanggb, Symbol yanggb1</span>
})</pre>
</div>
<p>这时候就会输出所有的Symbol属性,包括可枚举不可枚举Symbol属性。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">Reflect.ownKeys</span></p>
<p>Reflect.ownKeys()方法是ES2015新增的一个静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和Symbol属性。</p>
<div class="cnblogs_code">
<pre>Reflect.ownKeys(obj).forEach((key) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
console.log(obj) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> yanggb, yanggb1, Symbol yanggb, Symbol yanggb1</span>
})</pre>
</div>
<p>既然方法有那么多,自然需要对比一下才能知道不同的场景该怎么选用。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">几种方法的对比</span></p>
<p>通过一个表格直观得对比:</p>
<table>
<thead></thead>
<tbody>
<tr>
<td><strong>方式</strong></td>
<td><strong>基本属性</strong></td>
<td><strong>原型链</strong></td>
<td><strong>不可枚举</strong></td>
<td><strong>Symbol</strong></td>
</tr>
<tr>
<td>for in</td>
<td>是</td>
<td>是</td>
<td>否</td>
<td>否</td>
</tr>
<tr>
<td>Object.keys()</td>
<td>是</td>
<td>否</td>
<td>否</td>
<td>否</td>
</tr>
<tr>
<td>Object.getOwnPropertyNames()</td>
<td>是</td>
<td>否</td>
<td>是</td>
<td>否</td>
</tr>
<tr>
<td>Object.getOwnPropertySymbols()</td>
<td>否</td>
<td>否</td>
<td>是</td>
<td>是</td>
</tr>
<tr>
<td>Reflect.ownKeys()</td>
<td>是</td>
<td>否</td>
<td>是</td>
<td>是</td>
</tr>
</tbody>
</table>
<p>这其中只有for in循环会得到对象原型链上的属性,其它方法都只适用于对象自身的属性。</p>
<p>ES语言后续添加的新特性不会对以前的代码产生副作用,比如在ES2015之前就存在的for in循环,Object.keys()和Object.getOwnPropertyNames()是肯定不会返回Symbol属性的。</p>
<p>&nbsp;</p>
<p>"成长的经历,大概能让人变得越来越安静。"</p>

</div>
<div id="MySignature" role="contentinfo">
    你要去做一个大人,不要回头,不要难过。<br><br>
来源:https://www.cnblogs.com/yanggb/p/13568354.html
頁: [1]
查看完整版本: javascript遍历对象的几种方法