2019-04-21 11:50:48 +08:00

162 lines
9.2 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><strong><code>handler.ownKeys()</code></strong> 方法用于拦截 <a href="Reference/Global_Objects/Reflect/ownKeys" title="静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。"><code>Reflect.ownKeys()</code></a>.</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">var p = new Proxy(target, {
ownKeys: function(target) {
}
});
</code></pre>
<h3 id="参数">参数</h3>
<p>下面的参数被传递给<code>ownKeys。this</code>被绑定在<code>handler上。</code></p>
<dl>
<dt><code>target</code></dt>
<dd>目标对象.</dd>
</dl>
<h3 id="返回值">返回值</h3>
<p><code>ownKeys</code> 方法必须返回一个可枚举对象.</p>
<h2 id="描述">描述</h2>
<p><code><strong>handler.ownKeys()</strong></code> 方法用于拦截 <a href="Reference/Global_Objects/Reflect/ownKeys" title="静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。"><code>Reflect.ownKeys()</code></a>.</p>
<h3 id="拦截">拦截</h3>
<p>该拦截器可以拦截以下操作::</p>
<ul>
<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/getOwnPropertySymbols" title="Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。"><code>Object.getOwnPropertySymbols()</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/Reflect/ownKeys" title="静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。"><code>Reflect.ownKeys()</code></a></li>
</ul>
<h3 id="约定">约定</h3>
<p>如果违反了下面的约定proxy将抛出错误 <a href="Reference/Global_Objects/TypeError" title="TypeError类型错误 对象用来表示值的类型非预期类型时发生的错误。"><code>TypeError</code></a>:</p>
<ul>
<li><code>ownKeys</code> 的结果必须是一个数组.</li>
<li>数组的元素类型要么是一个 <a href="Reference/String" title="此页面仍未被本地化, 期待您的翻译!"><code>String</code></a> ,要么是一个 <a href="Reference/Global_Objects/Symbol" title='Symbol()函数会返回symbol类型的值该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象它的静态方法会暴露全局的symbol注册且类似于内建对象类但作为构造函数来说它并不完整因为它不支持语法"new Symbol()"。'><code>Symbol</code></a>.</li>
<li>结果列表必须包含目标对象的所有不可配置non-configurable 、自有own属性的key.</li>
<li>如果目标对象不可扩展那么结果列表必须包含目标对象的所有自有own属性的key不能有其它值.</li>
</ul>
<h2 id="示例">示例</h2>
<p>下面的代码拦截 <a href="Reference/Global_Objects/Object/getOwnPropertyNames" title="Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名包括不可枚举属性但不包括Symbol值作为名称的属性组成的数组。"><code>Object.getOwnPropertyNames()</code></a>.</p>
<pre><code class="language-javascript">var p = new Proxy({}, {
ownKeys: function(target) {
console.log('called');
return ['a', 'b', 'c'];
}
});
console.log(Object.getOwnPropertyNames(p)); // "called"
// [ 'a', 'b', 'c' ]</code></pre>
<p>下面的代码违反了约定</p>
<pre><code class="language-js example-bad">var obj = {};
Object.defineProperty(obj, 'a', {
configurable: false,
enumerable: true,
value: 10 }
);
var p = new Proxy(obj, {
ownKeys: function(target) {
return [123, 12.5, true, false, undefined, null, {}, []];
}
});
console.log(Object.getOwnPropertyNames(p));
// TypeError: proxy [[OwnPropertyKeys]] 必须返回一个数组
// 数组元素类型只能是String或Symbol
</code></pre>
<h2 id="标准">标准</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">[[OwnPropertyKeys]]</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Initial definition.</td>
</tr>
<tr>
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">[[OwnPropertyKeys]]</small></a></td>
<td><span class="spec-Draft">Draft</span></td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容">浏览器兼容</h2>
<div><div class="blockIndicator warning"><strong><a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">We're converting our compatibility data into a machine-readable JSON format</a></strong>.
This compatibility table still uses the old format,
because we haven't yet converted the data it contains.
<strong><a class="new" href="/zh-CN/docs/MDN/Contribute/Structures/Compatibility_tables" rel="nofollow">Find out how you can help!</a></strong></div>
<div class="htab">
<a id="AutoCompatibilityTable" name="AutoCompatibilityTable"></a>
<ul>
<li class="selected"><a>Desktop</a></li>
<li><a>Mobile</a></li>
</ul>
</div></div>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><a href="/en-US/Firefox/Releases/18" title="Released on 2013-01-08.">18</a> (18)</td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Chrome for Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td>18.0 (18)</td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
<td><span style="color: rgb(255, 153, 0);" title="Compatibility unknown; please update this.">?</span></td>
</tr>
</tbody>
</table>
</div>
<h2 id="兼容性注意事项">兼容性注意事项</h2>
<h3 id="Firefox火狐">Firefox火狐</h3>
<ul>
<li>在Gecko 42 (Firefox 42 / Thunderbird 42 / SeaMonkey 2.39)版本中, <code>ownKey</code> 的实施已经更新了为了反映最终的ES5标准 (see <a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1049662" rel="noopener" title='FIXED: Update ES6 scripted proxies "ownKeys" to ES6 final'>bug 1049662</a>):
<ul>
<li>现在需要检查结果是不是数组以及数组元素类型是不是string或symbol.</li>
<li>枚举重复的自有的属性名称不再失败.</li>
</ul>
</li>
</ul>
<h2 id="另见">另见</h2>
<ul>
<li><a href="Reference/Global_Objects/Proxy" title="Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。"><code>Proxy</code></a></li>
<li><a href="Reference/Global_Objects/Proxy/handler" title="处理器对象用来自定义代理对象的各种可代理操作。"><code>handler</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/Reflect/ownKeys" title="静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。"><code>Reflect.ownKeys()</code></a></li>
</ul>
</article>