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

204 lines
17 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>get</code></strong>语法将对象属性绑定到查询该属性时将被调用的函数。</p>
<div><iframe class="interactive interactive-js" frameborder="0" height="250" src="https://interactive-examples.mdn.mozilla.net/pages/js/functions-getter.html" width="100%"></iframe></div>
<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a class="external" href="https://github.com/mdn/interactive-examples" rel="noopener">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">{get <em>prop</em>() { ... } }
{get <em>[expression]</em>() { ... } }</code></pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>prop</code></dt>
<dd>要绑定到给定函数的属性名。</dd>
<dt>expression</dt>
<dd>从 ECMAScript 2015 开始,还可以使用一个计算属性名的表达式绑定到给定的函数。</dd>
</dl>
<h2 id="描述">描述</h2>
<p>有时需要允许访问返回动态计算值的属性或者你可能需要反映内部变量的状态而不需要使用显式方法调用。在JavaScript中可以使用 <em>getter </em>来实现。虽然可以使用 getter 和 setter 来创建一个伪属性类型,但是不可能同时将一个 getter 绑定到一个属性并且该属性实际上具有一个值。</p>
<p>使用<code>get</code>语法时应注意以下问题:</p>
<div>
<ul>
<li>可以使用数值或字符串作为标识;</li>
<li>必须不带参数(请参考<a class="external" href="http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/" rel="external nofollow noopener">Incompatible <abbr title="ECMAScript 5th edition">ES5</abbr> change: literal getter and setter functions must now have exactly zero or one arguments</a></li>
<li>它不能与另一个 <code>get </code>或具有相同属性的数据条目同时出现在一个对象字面量中(不允许使用 <code>{ get x() { }, get x() { } }</code><code>{ x: ..., get x() { } }</code>)。</li>
</ul>
</div>
<p>可通过 <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete" title="en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator">delete</a></code> 操作符删除 getter。</p>
<h2 id="示例">示例</h2>
<h3 id="Example:_Defining_a_getter_with_the_get_operator" name="Example:_Defining_a_getter_with_the_get_operator">在新对象初始化时定义一个getter</h3>
<p>这会为<code>obj</code>创建一个伪属性<code>latest</code>,它会返回<code>log</code>数组的最后一个元素。</p>
<pre><code class="language-javascript">var obj = {
log: ['example','test'],
get latest() {
if (this.log.length == 0) return undefined;
return this.log[this.log.length - 1];
}
}
console.log(obj.latest); // "test".</code></pre>
<p>注意,尝试为<code>latest</code>分配一个值不会改变它。</p>
<h3 id="Example:_Deleting_a_getter_using_the_delete_operator" name="Example:_Deleting_a_getter_using_the_delete_operator">使用<code>delete</code>操作符删除 getter</h3>
<p>只需使用 <code><a href="Reference/Operators/delete">delete</a></code>,就可删除 getter</p>
<pre><code class="language-javascript">delete obj.latest;
</code></pre>
<h3 id="使用defineProperty在现有对象上定义_getter">使用<code>defineProperty</code>在现有对象上定义 getter</h3>
<p>要随时将 getter 添加到现有对象,使用 <a href="Reference/Global_Objects/Object/defineProperty" title="Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。"><code>Object.defineProperty()</code></a>.</p>
<pre><code class="language-javascript">var o = { a:0 }
Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });
console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)</code></pre>
<h3 id="使用计算属性名">使用计算属性名</h3>
<pre><code class="language-javascript">var expr = 'foo';
var obj = {
get [expr]() { return 'bar'; }
};
console.log(obj.foo); // "bar"</code></pre>
<h3 id="Smart_self-overwriting_lazy_getters">Smart / self-overwriting / lazy getters</h3>
<p>Getters 给你一种方法来定义一个对象的属性,但是在访问它们之前不会计算属性的值。 getter 延续计算值的成本,直到需要值,如果不需要,您就不用支付成本。</p>
<p>一种额外的优化技术是用<strong>智能或<a class="external" href="https://en.wikipedia.org/wiki/Memoization" rel="noopener">记忆化</a> getters </strong>延迟属性值的计算并将其缓存以备以后访问。该值是在第一次调用getter 时计算的,然后被缓存,因此后续访问返回缓存值而不重新计算它。这在以下情况下很有用:</p>
<ul>
<li>如果属性值的计算是昂贵的占用大量RAM或CPU时间产生工作线程检索远程文件等</li>
<li>如果现在不需要该值。它将在稍后使用,或在某些情况下它根本不使用。</li>
<li>如果被使用,它将被访问几次,并且不需要重新计算该值将永远不会被改变,或者不应该被重新计算。</li>
</ul>
<p>这意味着你不应该为你希望更改其值的属性使用懒 getter因为 getter 不会重新计算该值。</p>
<p>在以下示例中,对象具有一个 getter 属性。在获取属性时,该属性将从对象中删除并重新添加,但此时将隐式显示为数据属性。最后返回得到值。</p>
<pre><code class="language-javascript">get notifier() {
delete this.notifier;
return this.notifier = document.getElementById('bookmarked-notification-anchor');
},
</code></pre>
<p>对于Firefox代码另请参阅定义<code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter()">defineLazyGetter()</a></code>函数的XPCOMUtils.jsm代码模块。</p>
<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/5.1/#sec-11.1.5" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">Object Initializer</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Initial definition.</td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Method definitions</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Added computed property names.</td>
</tr>
<tr>
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-method-definitions" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Method definitions</small></a></td>
<td><span class="spec-Draft">Draft</span></td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容">浏览器兼容</h2>
<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div>
<p></p><div class="bc-data"><a class="bc-github-link external" href="https://github.com/mdn/browser-compat-data" rel="noopener">Update compatibility data on GitHub</a><table class="bc-table bc-table-js"><thead><tr class="bc-platforms"><td></td><th class="bc-platform-desktop" colspan="6"><span>Desktop</span></th><th class="bc-platform-mobile" colspan="7"><span>Mobile</span></th><th class="bc-platform-server" colspan="1"><span>Server</span></th></tr><tr class="bc-browsers"><td></td><th class="bc-browser-chrome"><span class="bc-head-txt-label bc-head-icon-chrome">Chrome</span></th><th class="bc-browser-edge"><span class="bc-head-txt-label bc-head-icon-edge">Edge</span></th><th class="bc-browser-firefox"><span class="bc-head-txt-label bc-head-icon-firefox">Firefox</span></th><th class="bc-browser-ie"><span class="bc-head-txt-label bc-head-icon-ie">Internet Explorer</span></th><th class="bc-browser-opera"><span class="bc-head-txt-label bc-head-icon-opera">Opera</span></th><th class="bc-browser-safari"><span class="bc-head-txt-label bc-head-icon-safari">Safari</span></th><th class="bc-browser-webview_android"><span class="bc-head-txt-label bc-head-icon-webview_android">Android webview</span></th><th class="bc-browser-chrome_android"><span class="bc-head-txt-label bc-head-icon-chrome_android">Chrome for Android</span></th><th class="bc-browser-edge_mobile"><span class="bc-head-txt-label bc-head-icon-edge_mobile">Edge Mobile</span></th><th class="bc-browser-firefox_android"><span class="bc-head-txt-label bc-head-icon-firefox_android">Firefox for Android</span></th><th class="bc-browser-opera_android"><span class="bc-head-txt-label bc-head-icon-opera_android">Opera for Android</span></th><th class="bc-browser-safari_ios"><span class="bc-head-txt-label bc-head-icon-safari_ios">Safari on iOS</span></th><th class="bc-browser-samsunginternet_android"><span class="bc-head-txt-label bc-head-icon-samsunginternet_android">Samsung Internet</span></th><th class="bc-browser-nodejs"><span class="bc-head-txt-label bc-head-icon-nodejs">Node.js</span></th></tr></thead><tbody><tr><th scope="row"><code>get</code></th><td class="bc-supports-yes bc-browser-chrome"><span class="bc-browser-name">Chrome</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
1</td><td class="bc-supports-yes bc-browser-edge"><span class="bc-browser-name">Edge</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-firefox"><span class="bc-browser-name">Firefox</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
2</td><td class="bc-supports-yes bc-browser-ie"><span class="bc-browser-name">IE</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
9</td><td class="bc-supports-yes bc-browser-opera"><span class="bc-browser-name">Opera</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
9.5</td><td class="bc-supports-yes bc-browser-safari"><span class="bc-browser-name">Safari</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
3</td><td class="bc-supports-yes bc-browser-webview_android"><span class="bc-browser-name">WebView Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
1</td><td class="bc-supports-yes bc-browser-chrome_android"><span class="bc-browser-name">Chrome Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
18</td><td class="bc-supports-yes bc-browser-edge_mobile"><span class="bc-browser-name">Edge Mobile</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-firefox_android"><span class="bc-browser-name">Firefox Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
4</td><td class="bc-supports-yes bc-browser-opera_android"><span class="bc-browser-name">Opera Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-safari_ios"><span class="bc-browser-name">Safari iOS</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-samsunginternet_android"><span class="bc-browser-name">Samsung Internet Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-nodejs"><span class="bc-browser-name">nodejs</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td></tr><tr><th scope="row">Computed property names</th><td class="bc-supports-yes bc-browser-chrome"><span class="bc-browser-name">Chrome</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
46</td><td class="bc-supports-yes bc-browser-edge"><span class="bc-browser-name">Edge</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-firefox"><span class="bc-browser-name">Firefox</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
34</td><td class="bc-supports-no bc-browser-ie"><span class="bc-browser-name">IE</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-yes bc-browser-opera"><span class="bc-browser-name">Opera</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
47</td><td class="bc-supports-no bc-browser-safari"><span class="bc-browser-name">Safari</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-yes bc-browser-webview_android"><span class="bc-browser-name">WebView Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
46</td><td class="bc-supports-yes bc-browser-chrome_android"><span class="bc-browser-name">Chrome Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
46</td><td class="bc-supports-yes bc-browser-edge_mobile"><span class="bc-browser-name">Edge Mobile</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-yes bc-browser-firefox_android"><span class="bc-browser-name">Firefox Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
34</td><td class="bc-supports-yes bc-browser-opera_android"><span class="bc-browser-name">Opera Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td><td class="bc-supports-no bc-browser-safari_ios"><span class="bc-browser-name">Safari iOS</span><abbr class="bc-level-no only-icon" title="No support">
<span>No support</span>
</abbr>
No</td><td class="bc-supports-yes bc-browser-samsunginternet_android"><span class="bc-browser-name">Samsung Internet Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
5.0</td><td class="bc-supports-yes bc-browser-nodejs"><span class="bc-browser-name">nodejs</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
Yes</td></tr></tbody></table><section class="bc-legend" id="sect1"><h3 class="offscreen" id="Legend">Legend</h3><dl><dt><span class="bc-supports-yes bc-supports">
<abbr class="bc-level bc-level-yes only-icon" title="Full support">
<span>Full support</span>
 
</abbr></span></dt><dd>Full support</dd><dt><span class="bc-supports-no bc-supports">
<abbr class="bc-level bc-level-no only-icon" title="No support">
<span>No support</span>
 
</abbr></span></dt><dd>No support</dd></dl></section></div><p></p>
<h2 id="See_also" name="See_also">相关链接</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a></li>
<li><a href="Reference/Operators/delete" title="delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。"><code>delete</code></a></li>
<li><a href="Reference/Global_Objects/Object/defineProperty" title="Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。"><code>Object.defineProperty()</code></a></li>
<li><a class="new" href="Reference/Global_Objects/Object/defineGetter" rel="nofollow" title="此页面仍未被本地化, 期待您的翻译!"><code>__defineGetter__</code></a></li>
<li><a class="new" href="Reference/Global_Objects/Object/defineSetter" rel="nofollow" title="此页面仍未被本地化, 期待您的翻译!"><code>__defineSetter__</code></a></li>
<li>在Javascript指南中 <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">定义Getters和Setters</a></li>
</ul>
</article>