uTools-Manuals/docs/javascript/Enumerability_and_ownership_of_properties.html
2019-04-21 11:50:48 +08:00

306 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<article id="wikiArticle">
<div></div>
<p>可枚举属性是指那些内部 “可枚举” 标志设置为 true 的属性,对于通过直接的赋值和属性初始化的属性,该标识值默认为即为 true对于通过 <a href="Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a> 等定义的属性,该标识值默认为 false。可枚举的属性可以通过 <a href="Reference/Statements/for...in">for...in</a> 循环进行遍历(除非该属性名是一个 <a href="Reference/Global_Objects/Symbol">Symbol</a>)。属性的所有权是通过判断该属性是否直接属于某个对象决定的,而不是通过原型链继承的。一个对象的所有的属性可以一次性的获取到。有一些内置的方法可以用于判断、迭代/枚举以及获取对象的一个或一组属性,下表对这些方法进行了列举。对于部分不可用的类别,下方的示例代码对获取方法进行了演示。</p>
<div style="overflow: auto; width: 100%;">
<table>
<caption>属性的可枚举性和所有权 - 内置的判断、访问和迭代方法</caption>
<tbody>
<tr>
<th>功能</th>
<th>自身对象</th>
<th>自身对象及其原型链</th>
<th>仅原型链</th>
</tr>
<tr>
<td>判断</td>
<td>
<table>
<thead>
<tr>
<th scope="col">可枚举属性</th>
<th scope="col">不可枚举属性</th>
<th scope="col">可枚举属性及不可枚举属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable">propertyIsEnumerable</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">hasOwnProperty</a></code></p>
</td>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">hasOwnProperty</a></code> filtered to exclude enumerables using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable">propertyIsEnumerable</a></code></p>
</td>
<td><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">hasOwnProperty</a></code></td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<thead>
<tr>
<th scope="col">可枚举属性</th>
<th scope="col">不可枚举属性</th>
<th scope="col">可枚举属性及不可枚举属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>需要额外代码实现</td>
<td>需要额外代码实现</td>
<td><code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/in">in</a></code></td>
</tr>
</tbody>
</table>
</td>
<td>需要额外代码实现</td>
</tr>
<tr>
<td>访问</td>
<td>
<table>
<thead>
<tr>
<th scope="col">可枚举属性</th>
<th scope="col">不可枚举属性</th>
<th scope="col">可枚举属性及不可枚举属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a></code></p>
</td>
<td><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a> </code> filtered to exclude enumerables using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable">propertyIsEnumerable</a></code></td>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a></code></p>
</td>
</tr>
</tbody>
</table>
</td>
<td>需要额外代码实现</td>
<td>需要额外代码实现</td>
</tr>
<tr>
<td>迭代</td>
<td>
<table>
<thead>
<tr>
<th scope="col">可枚举属性</th>
<th scope="col">不可枚举属性</th>
<th scope="col">可枚举属性及不可枚举属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a></code></p>
</td>
<td><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a></code> filtered to exclude enumerables using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable">propertyIsEnumerable</a></code></td>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">getOwnPropertyNames</a></code></p>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">getOwnPropertySymbols</a></code></p>
</td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<thead>
<tr>
<th scope="col">可枚举属性</th>
<th scope="col">不可枚举属性</th>
<th scope="col">可枚举属性及不可枚举属性</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...in">for..in</a></code></p>
<p>(excluding symbols)</p>
</td>
<td>需要额外代码实现</td>
<td>需要额外代码实现</td>
</tr>
</tbody>
</table>
</td>
<td>需要额外代码实现</td>
</tr>
</tbody>
</table>
</div>
<h2 id="通过可枚举性和所有权获取对象的属性">通过可枚举性和所有权获取对象的属性</h2>
<p>注:以下实现并非使用于所有情况的最优算法,但可以快捷的展示语言特性。</p>
<ul>
<li>使用 <code>SimplePropertyRetriever.theGetMethodYouWant(obj).indexOf(prop) &gt; -1</code> 时将发生判断操作。</li>
<li>使用 <code>SimplePropertyRetriever.theGetMethodYouWant(obj).forEach(function (value, prop) {});</code> 时将发生迭代操作。 (或使用 <code>filter()</code><code>map()</code> 等方法)</li>
</ul>
<pre><code class="language-javascript">var SimplePropertyRetriever = {
getOwnEnumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._enumerable);
// Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj);
},
getOwnNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._notEnumerable);
},
getOwnEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
// Or just use: return Object.getOwnPropertyNames(obj);
},
getPrototypeEnumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._enumerable);
},
getPrototypeNonenumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._notEnumerable);
},
getPrototypeEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
},
getOwnAndPrototypeEnumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._enumerable);
// Or could use unfiltered for..in
},
getOwnAndPrototypeNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._notEnumerable);
},
getOwnAndPrototypeEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
},
// Private static property checker callbacks
_enumerable: function(obj, prop) {
return obj.propertyIsEnumerable(prop);
},
_notEnumerable: function(obj, prop) {
return !obj.propertyIsEnumerable(prop);
},
_enumerableAndNotEnumerable: function(obj, prop) {
return true;
},
// Inspired by http://stackoverflow.com/a/8024294/271577
_getPropertyNames: function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
var props = [];
do {
if (iterateSelfBool) {
Object.getOwnPropertyNames(obj).forEach(function(prop) {
if (props.indexOf(prop) === -1 &amp;&amp; includePropCb(obj, prop)) {
props.push(prop);
}
});
}
if (!iteratePrototypeBool) {
break;
}
iterateSelfBool = true;
} while (obj = Object.getPrototypeOf(obj));
return props;
}
};</code></pre>
<h2 id="统计表">统计表</h2>
<div style="width: 100%; overflow: auto;">
<table>
<thead>
<tr>
<th scope="row"> </th>
<th scope="col"><code>in</code></th>
<th scope="col"><code>for..in</code></th>
<th scope="col"><code>obj.hasOwnProperty</code></th>
<th scope="col"><code>obj.propertyIsEnumerable</code></th>
<th scope="col"><code>Object.keys</code></th>
<th scope="col"><code>Object.getOwnPropertyNames</code></th>
<th scope="col"><code>Object.getOwnPropertyDescriptors</code></th>
<th scope="col"><code>Reflect.ownKeys()</code></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">可枚举自身属性</th>
<td>true</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>true</td>
</tr>
<tr>
<th scope="row">不可枚举自身属性</th>
<td>true</td>
<td>false</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>true</td>
<td>true</td>
<td>true</td>
</tr>
<tr>
<th scope="row">Symbols keys</th>
<td>true</td>
<td>false</td>
<td>true</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>true</td>
<td>true</td>
</tr>
<tr>
<th scope="row">可枚举继承属性</th>
<td>true</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
</tr>
<tr>
<th scope="row">不可枚举继承属性</th>
<td>true</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
</tr>
<tr>
<th scope="row">Inherited Symbols keys</th>
<td>true</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>false</td>
</tr>
</tbody>
</table>
</div>
<h2 id="参见">参见</h2>
<ul>
<li><code><a href="Reference/Operators/in">in</a></code></li>
<li><code><a href="Reference/Statements/for...in">for..in</a></code></li>
<li><a href="Reference/Global_Objects/Object/hasOwnProperty" title="hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性"><code>Object.hasOwnProperty()</code></a></li>
<li><a href="Reference/Global_Objects/Object/propertyIsEnumerable" title="propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举。"><code>Object.propertyIsEnumerable()</code></a></li>
<li><a href="Reference/Global_Objects/Object/getOwnPropertyNames" title="Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名包括不可枚举属性但不包括Symbol值作为名称的属性组成的数组。"><code>Object.getOwnPropertyNames()</code></a></li>
<li><a href="Reference/Global_Objects/Object/keys" title="Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。"><code>Object.keys()</code></a></li>
<li><a href="Reference/Global_Objects/Object/getOwnPropertyDescriptors" title="Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。"><code>Object.getOwnPropertyDescriptors()</code></a></li>
</ul>
</article>