mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-10 07:54:06 +08:00
237 lines
14 KiB
HTML
237 lines
14 KiB
HTML
<article id="wikiArticle">
|
||
<p></p><p></p>
|
||
<p>返回创建实例对象的 <a href="Reference/Global_Objects/Object" title="Object 构造函数创建一个对象包装器。"><code>Object</code></a> 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如<code>1</code>,<code>true</code>和<code>"test"</code>,该值只可读。</p>
|
||
<h2 id="Description" name="Description">描述</h2>
|
||
<p>所有对象都会从它的原型上继承一个 <code>constructor</code> 属性:</p>
|
||
<pre><code class="language-javascript">var o = {};
|
||
o.constructor === Object; // true
|
||
|
||
var o = new Object;
|
||
o.constructor === Object; // true
|
||
|
||
var a = [];
|
||
a.constructor === Array; // true
|
||
|
||
var a = new Array;
|
||
a.constructor === Array // true
|
||
|
||
var n = new Number(3);
|
||
n.constructor === Number; // true</code></pre>
|
||
<h2 id="Examples" name="Examples">示例</h2>
|
||
<h3 id="Example:_Displaying_the_constructor_of_an_object" name="Example:_Displaying_the_constructor_of_an_object">打印一个对象的构造函数</h3>
|
||
<p>以下示例创建一个原型,<code>Tree</code>,以及该类型的对象,即<code>theTree</code>。 然后打印<code>theTree</code>对象的<code>constructor</code>属性。</p>
|
||
<pre><code class="language-js">function Tree(name) {
|
||
this.name = name;
|
||
}
|
||
|
||
var theTree = new Tree("Redwood");
|
||
console.log( "theTree.constructor is " + theTree.constructor );</code></pre>
|
||
<p>打印输出:</p>
|
||
<pre><code class="language-js">theTree.constructor is function Tree(name) {
|
||
this.name = name;
|
||
}</code></pre>
|
||
<h3 id="Example:_Changing_the_constructor_of_an_object" name="Example:_Changing_the_constructor_of_an_object">改变对象的 constructor</h3>
|
||
<p>下面的例子展示了如何修改基本类型对象的 <code>constructor</code> 属性的值。只有 <code>true</code>, <code>1</code> 和 <code>"test"</code> 的不受影响,因为创建他们的是只读的原生构造函数(native constructors)。这个例子也说明了依赖一个对象的 <code>constructor</code> 属性并不安全。</p>
|
||
<pre><code class="language-js">function Type() { };
|
||
|
||
var types = [
|
||
new Array,
|
||
[],
|
||
new Boolean,
|
||
true, // remains unchanged
|
||
new Date,
|
||
new Error,
|
||
new Function,
|
||
function(){},
|
||
Math,
|
||
new Number,
|
||
1, // remains unchanged
|
||
new Object,
|
||
{},
|
||
new RegExp,
|
||
/(?:)/,
|
||
new String,
|
||
"test" // remains unchanged
|
||
];
|
||
|
||
for(var i = 0; i < types.length; i++) {
|
||
types[i].constructor = Type;
|
||
types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
|
||
};
|
||
|
||
console.log( types.join("\n") );
|
||
</code></pre>
|
||
<p>此示例显示以下输出:</p>
|
||
<pre><code class="language-javascript">function Type() {},false,
|
||
function Type() {},false,
|
||
function Type() {},false,false
|
||
function Boolean() {
|
||
[native code]
|
||
},false,true
|
||
function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600
|
||
function Type() {},false,Error
|
||
function Type() {},false,function anonymous() {
|
||
|
||
}
|
||
function Type() {},false,function () {}
|
||
function Type() {},false,[object Math]
|
||
function Type() {},false,0
|
||
function Number() {
|
||
[native code]
|
||
},false,1
|
||
function Type() {},false,[object Object]
|
||
function Type() {},false,[object Object]
|
||
function Type() {},false,/(?:)/
|
||
function Type() {},false,/(?:)/
|
||
function Type() {},false,
|
||
function String() {
|
||
[native code]
|
||
},false,test
|
||
</code></pre>
|
||
<p> </p>
|
||
<h3 id="改变函数的_constructor">改变函数的 constructor</h3>
|
||
<p>大多数情况下,此属性用于定义一个构造函数,并使用<strong>new</strong>和继承原型链进一步调用它。</p>
|
||
<pre><code class="language-javascript">function Parent() {}
|
||
Parent.prototype.parentMethod = function parentMethod() {};
|
||
|
||
function Child() {}
|
||
Child.prototype = Object.create(Parent.prototype); // re-define child prototype to Parent prototype
|
||
|
||
Child.prototype.constructor = Child; // return original constructor to Child</code></pre>
|
||
<p>但为什么我们需要在这里执行最后一行?很不幸正确答案是 - 看情况而定。</p>
|
||
<p>让我们尝试定义在哪些情况下重新分配原始构造函数将起主要作用,何时它将是一个额外的未使用的代码行。</p>
|
||
<p>试想下一种情况:该对象具有创建自身的<strong>create</strong>方法。</p>
|
||
<pre><code class="language-javascript">function Parent() {};
|
||
function CreatedConstructor() {}
|
||
|
||
CreatedConstructor.prototype = Object.create(Parent.prototype);
|
||
|
||
CreatedConstructor.prototype.create = function create() {
|
||
return new this.constructor();
|
||
}
|
||
|
||
new CreatedConstructor().create().create(); // error undefined is not a function since constructor === Parent
|
||
</code></pre>
|
||
<p>在上面的示例中,将显示异常,因为构造函数链接到Parent。</p>
|
||
<p>为了避免它,只需分配您将要使用的必要构造函数。</p>
|
||
<pre><code class="language-javascript">function Parent() {};
|
||
function CreatedConstructor() {}
|
||
|
||
CreatedConstructor.prototype = Object.create(Parent.prototype);
|
||
CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using
|
||
|
||
CreatedConstructor.prototype.create = function create() {
|
||
return new this.constructor();
|
||
}
|
||
|
||
new CreatedConstructor().create().create(); // it's pretty fine</code></pre>
|
||
<p>好的,现在很清楚为什么更改构造函数会很有用。</p>
|
||
<p>让我们再考虑一个案例。</p>
|
||
<pre><code class="language-javascript">function ParentWithStatic() {}
|
||
|
||
ParentWithStatic.startPosition = { x: 0, y:0 };
|
||
ParentWithStatic.getStartPosition = function getStartPosition() {
|
||
return this.startPosition;
|
||
}
|
||
|
||
function Child(x, y) {
|
||
this.position = {
|
||
x: x,
|
||
y: y
|
||
};
|
||
}
|
||
|
||
Child.prototype = Object.create(ParentWithStatic.prototype);
|
||
Child.prototype.constructor = Child;
|
||
|
||
Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() {
|
||
var position = this.position;
|
||
var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, since the constructor is Child
|
||
|
||
return {
|
||
offsetX: startPosition.x - position.x,
|
||
offsetY: startPosition.y - position.y
|
||
}
|
||
};</code></pre>
|
||
<p>对于此示例,我们需要保持父构造函数继续正常工作。</p>
|
||
<p><strong>总结</strong>:手动设置或更新构造函数可能会导致不同且有时令人困惑的后果。为了防止它,只需在每个特定情况下定义构造函数的角色。在大多数情况下,不使用构造函数,并且不需要重新分配构造函数。</p>
|
||
<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</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/publications/files/ECMA-ST-ARCH/ECMA-262,%201st%20edition,%20June%201997.pdf" hreflang="en" lang="en" rel="noopener" title="ECMAScript 1st Edition (ECMA-262)">ECMAScript 1st Edition (ECMA-262)</a></td>
|
||
<td><span class="spec-Standard">Standard</span></td>
|
||
<td>Initial definition. Implemented in JavaScript 1.1.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><a class="external" href="https://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4.1" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">Object.prototype.constructor</small></a></td>
|
||
<td><span class="spec-Standard">Standard</span></td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-object.prototype.constructor" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Object.prototype.constructor</small></a></td>
|
||
<td><span class="spec-Standard">Standard</span></td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-object.prototype.constructor" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Object.prototype.constructor</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>constructor</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>
|
||
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>
|
||
12</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>
|
||
Yes</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></dl></section></div><p></p>
|
||
</article> |