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

156 lines
18 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 class="blockIndicator deprecated deprecatedHeader">
<p><strong><span class="icon-only-inline" title="This is an obsolete API and is no longer guaranteed to work."><i class="icon-trash"> </i></span> 已废弃</strong><br/>该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。</p>
</div></div>
<div class="warning">
<p><strong>警告:</strong> 通过现代浏览器的操作属性的便利性,可以改变一个对象的 <code>[[Prototype]]</code> 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作使用这种方式来改变和继承属性是对性能影响非常严重的并且性能消耗的时间也不是简单的花费在 <code>obj.__proto__ = ...</code> 语句上, 它还会影响到所有继承来自该 <code>[[Prototype]]</code> 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。相反, 创建一个新的且可以继承 <code>[[Prototype]]</code> 的对象,推荐使用 <a href="Reference/Global_Objects/Object/create" title="Object.create()方法创建一个新对象使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)"><code>Object.create()</code></a></p>
</div>
<div class="warning">
<p><strong>警告:</strong><code>Object.prototype.__proto__</code> 已被大多数浏览器厂商所支持的今天其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能以确保Web浏览器的兼容性。为了更好的支持建议只使用 <a href="Reference/Global_Objects/Object/getPrototypeOf" title="Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。"><code>Object.getPrototypeOf()</code></a></p>
</div>
<div><a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a> 的 <code>__proto__</code>  属性是一个访问器属性一个getter函数和一个setter函数, 暴露了通过它访问的对象的内部<code>[[Prototype]]</code> (一个对象或 <a href="Reference/Global_Objects/null" title="值 null 特指对象的值未设置。它是 JavaScript 基本类型 之一。"><code>null</code></a>)。</div>
<div> </div>
<p>使用<code>__proto__</code>是有争议的也不鼓励使用它。因为它从来没有被包括在EcmaScript语言规范中但是现代浏览器都实现了它。<code>__proto__</code>属性已在ECMAScript 6语言规范中标准化用于确保Web浏览器的兼容性因此它未来将被支持。它已被不推荐使用, 现在更推荐使用<a href="Reference/Global_Objects/Object/getPrototypeOf" title="Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。"><code>Object.getPrototypeOf</code></a>/<a href="Reference/Global_Objects/Reflect/getPrototypeOf" title="静态方法 Reflect.getPrototypeOf() 与 Object.getPrototypeOf() 方法是一样的。都是返回指定对象的原型(即,内部的 [[Prototype]] 属性的值)。"><code>Reflect.getPrototypeOf</code></a><a href="Reference/Global_Objects/Object/setPrototypeOf" title="如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible()查看)就会抛出 TypeError异常。如果prototype参数不是一个对象或者null(例如数字字符串boolean或者 undefined)则什么都不做。否则该方法将obj的[[Prototype]]修改为新的值。"><code>Object.setPrototypeOf</code></a>/<a href="Reference/Global_Objects/Reflect/setPrototypeOf" title="静态方法 Reflect.setPrototypeOf() 与 Object.setPrototypeOf() 方法是一致的。它将指定对象的原型 (即,内部的[[Prototype]] 属性设置为另一个对象或为 null。"><code>Reflect.setPrototypeOf</code></a>(尽管如此,设置对象的[[Prototype]]是一个缓慢的操作,如果性能是一个问题,应该避免)。</p>
<p>__proto__ 属性也可以在对象文字定义中使用对象[[Prototype]]来创建,作为<a href="Reference/Global_Objects/Object/create" title="Object.create()方法创建一个新对象使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)"><code>Object.create()</code></a> 的一个替代。 请参阅: <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">object initializer / literal syntax</a>.</p>
<h2 id="语法">语法</h2>
<pre><code class="language-javascript">let Circle = function () {};
let shape = {};
let circle = new Circle();
// 设置该对象的原型链引用
// 过时且不推荐使用的。这里只是举个例子,尽量不要在生产环境中这样做。
shape.__proto__ = circle;
// 判断该对象的原型链引用是否属于circle
console.log(shape.__proto__ === circle); // true
</code></pre>
<pre><code class="language-javascript">let shape = function () {};
let p = {
a: function () {
console.log('aaa');
}
};
shape.prototype.__proto__ = p;
let circle = new shape();
circle.a();//aaa
console.log(shape.prototype === circle.__proto__);//true
//或者
let shape = function () {};
var p = {
a: function () {
console.log('a');
}
};
let circle = new shape();
circle.__proto__ = p;
circle.a(); // a
console.log(shape.prototype === circle.__proto__);//false
//或者
function test() {}
test.prototype.myname = function () {
console.log('myname');
}
let a = new test()
console.log(a.__proto__ === test.prototype);//true
a.myname();//myname
//或者
let fn = function () {};
fn.prototype.myname = function () {
console.log('myname');
}
let obj = {
__proto__: fn.prototype
};
obj.myname();//myname
</code></pre>
<p>注意:这是两个下划线,后面是五个字符的 “proto” ,后面再跟两个下划线。</p>
<h2 id="描述">描述</h2>
<p>__proto__的读取器(getter)暴露了一个对象的内部 <code>[[Prototype]]</code> 。对于使用对象字面量创建的对象,这个值是 <a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a>。对于使用数组字面量创建的对象,这个值是 <a href="Reference/Global_Objects/Array/prototype" title="Array.prototype  属性表示 Array 构造函数的原型并允许您向所有Array对象添加新的属性和方法。"><code>Array.prototype</code></a>。对于functions这个值是<a href="Reference/Global_Objects/Function/prototype" title="Function.prototype 属性存储了 Function 的原型对象。"><code>Function.prototype</code></a>。对于使用 new fun 创建的对象其中fun是由js提供的内建构造器函数之一(<a href="Reference/Array" title="REDIRECT Array"><code>Array</code></a>, <a href="Reference/Boolean" title="此页面仍未被本地化, 期待您的翻译!"><code>Boolean</code></a>, <a href="Reference/Date" title="此页面仍未被本地化, 期待您的翻译!"><code>Date</code></a>, <a href="Reference/Global_Objects/Number" title="JavaScript 的 Number 对象是经过封装的能让你处理数字值的对象。Number 对象由 Number() 构造器创建。"><code>Number</code></a>, <a href="Reference/Global_Objects/Object" title="Object 构造函数创建一个对象包装器。"><code>Object</code></a>, <a href="Reference/String" title="此页面仍未被本地化, 期待您的翻译!"><code>String</code></a> 等等这个值总是fun.prototype。对于用js定义的其他js构造器函数创建的对象这个值就是该构造器函数的prototype属性。</p>
<p>__proto__ 的设置器(setter)允许对象的 <code>[[Prototype]]被变更。前提是这个对象必须通过</code> <a href="Reference/Global_Objects/Object/isExtensible" title="Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。"><code>Object.isExtensible()</code></a> 判断为是可扩展的,如果不可扩展,则会抛出一个 <a href="Reference/Global_Objects/TypeError" title="TypeError类型错误 对象用来表示值的类型非预期类型时发生的错误。"><code>TypeError</code></a> 错误。要变更的值必须是一个object或<a href="Reference/Global_Objects/null" title="值 null 特指对象的值未设置。它是 JavaScript 基本类型 之一。"><code>null</code></a>,提供其它值将不起任何作用。</p>
<p>要理解原型如何被使用,请查看相关文章:<a href="/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">Inheritance and the prototype chain</a></p>
<p>.__proto__属性是<a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a> 一个简单的访问器属性其中包含了get获取和set设置的方法任何一个__proto__的存取属性都继承于<a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a>,但一个访问属性如果不是来源于<a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a>就不拥有.__proto__属性譬如一个元素设置了其他的.__proto__属性在<a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a>之前,将会覆盖原有的<a href="Reference/Global_Objects/Object/prototype" title="Object.prototype 属性表示 Object 的原型对象。"><code>Object.prototype</code></a></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/6.0/#sec-additional-properties-of-the-object.prototype-object" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Object.prototype.__proto__</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Included in the (normative) annex for additional ECMAScript legacy features for Web browsers (note that the specification codifies what is already in implementations).</td>
</tr>
<tr>
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-additional-properties-of-the-object.prototype-object" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Object.prototype.__proto__</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>__proto__</code> <div class="bc-icons"><abbr class="only-icon" title="Deprecated. Not for use in new websites."><span>Deprecated</span><i class="ic-deprecated"></i></abbr></div></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>
Yes</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>
1</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>
11</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>
Yes</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>
Yes</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>
Yes</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>
Yes</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></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><abbr class="only-icon" title="Deprecated. Not for use in new websites."><span>Deprecated. Not for use in new websites.</span><i class="ic-deprecated"></i></abbr></dt><dd>Deprecated. Not for use in new websites.</dd></dl></section></div><p></p>
<h2 id="兼容性注意事项">兼容性注意事项</h2>
<p>在 ECMAScript 2015ES6的规范要求中支持<code>__proto__</code> 是各大Web浏览器厂商的要求虽然符合规范但其他环境下因为历史遗留的问题也有可能被使用和支持。 </p>
<h2 id="更多请参考">更多请参考</h2>
<ul>
<li><a href="Reference/Global_Objects/Object/isPrototypeOf" title="isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。"><code>Object.prototype.isPrototypeOf()</code></a></li>
<li><a href="Reference/Global_Objects/Object/getPrototypeOf" title="Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。"><code>Object.getPrototypeOf()</code></a></li>
<li><a href="Reference/Global_Objects/Object/setPrototypeOf" title="如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible()查看)就会抛出 TypeError异常。如果prototype参数不是一个对象或者null(例如数字字符串boolean或者 undefined)则什么都不做。否则该方法将obj的[[Prototype]]修改为新的值。"><code>Object.setPrototypeOf()</code></a></li>
</ul>
</article>