Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 929403 of Object.create()

  • 版本网址缩略名: Web/JavaScript/Reference/Global_Objects/Object/create
  • 版本标题: Object.create()
  • 版本 id: 929403
  • 创建于:
  • 创建者: ouonet
  • 是否是当前版本?
  • 评论

修订内容

{{JSRef("Global_Objects", "Object")}}

概述

Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。

语法

Object.create(proto, [ propertiesObject ])

参数

proto
一个对象,作为新创建对象的原型。
propertiesObject
可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与{{jsxref("Object.defineProperties()")}}的第二个参数一样)。注意:该参数对象不能是 {{jsxref("Global_Objects/undefined", "undefined")}},另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

抛出异常

如果 proto 参数不是 null 或一个对象值,则抛出一个 {{jsxref("Global_Objects/TypeError", "TypeError")}} 异常。

例子

使用Object.create实现类式继承

下面的例子演示了如何使用Object.create来实现类式继承。这是一个单继承。

//Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); //call super constructor.
}

Rectangle.prototype = Object.create(Shape.prototype);

var rect = new Rectangle();

rect instanceof Rectangle //true.
rect instanceof Shape //true.

rect.move(1, 1); //Outputs, "Shape moved."

如果你希望能继承到多个对象,则可以使用混入的方式。

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); //inherit
mixin(MyClass.prototype, OtherSuperClass.prototype); //mixin

MyClass.prototype.myMethod = function() {
     // do a thing
};

mixin函数会把超类原型上的函数拷贝到子类原型上,这里mixin函数没有给出,需要由你实现。一个和 mixin 很像的函数是  jQuery.extend

使用Object.create 的 propertyObject 参数

var o;

// 创建一个原型为null的空对象
o = Object.create(null);


o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);


o = Object.create(Object.prototype, {
  // foo会成为所创建对象的数据属性
  foo: { writable:true, configurable:true, value: "hello" },
  // bar会成为所创建对象的访问器属性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) { console.log("Setting `o.bar` to", value) }
}})


function Constructor(){}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype);
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码


// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })

// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
//"q"

delete o.p
//false

//创建一个可写的,可枚举的,可配置的属性p
o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });

Polyfill

这个polyfill只实现了创建一个指定原型的对象的功能,而不能同时添加特定的属性,也就是没有实现原生的Object.create函数中的第二个参数。

if (typeof Object.create != 'function') {
    (function () {
        var F = function () {};
        Object.create = function (o) {
            if (arguments.length > 1) {
              throw Error('Second argument not supported');
            }
            if (o === null) {
              throw Error('Cannot set a null [[Prototype]]');
            }
            if (typeof o != 'object') {
              throw TypeError('Argument must be an object');
            }
            F.prototype = o;
            return new F();
        };
    })();
}

规范

规范版本 规范状态 注解
{{SpecName('ES5.1', '#sec-15.2.3.5', 'Object.create')}} {{Spec2('ES5.1')}} Initial definition. Implemented in JavaScript 1.8.5
{{SpecName('ES6', '#sec-object.create', 'Object.create')}} {{Spec2('ES6')}}  

浏览器兼容性

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 5 {{ CompatGeckoDesktop("2") }} 9 11.60 5
Feature Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatGeckoDesktop("2") }} {{ CompatVersionUnknown() }} {{ CompatUnknown() }} 11.50 {{ CompatVersionUnknown() }}

相关链接

  • {{jsxref("Object.defineProperty")}}
  • {{jsxref("Object.defineProperties")}}
  • {{jsxref("Object.prototype.isPrototypeOf")}}
  • John Resig's post on getPrototypeOf

修订版来源

<p name="Summary">{{JSRef("Global_Objects", "Object")}}</p>

<h2 id="Summary" name="Summary">概述</h2>

<p><strong><code>Object.create()</code></strong> 方法创建一个拥有指定原型和若干个指定属性的对象。</p>

<h2 id="Syntax" name="Syntax">语法</h2>

<pre class="syntaxbox">
<code>Object.create(<em>proto,</em> [ <em>propertiesObject</em> ])</code></pre>

<h2 id="Parameters" name="Parameters">参数</h2>

<dl>
 <dt>proto</dt>
 <dd>一个对象,作为新创建对象的原型。</dd>
 <dt>propertiesObject</dt>
 <dd>可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与{{jsxref("Object.defineProperties()")}}的第二个参数一样)。注意:该参数对象不能是&nbsp;{{jsxref("Global_Objects/undefined", "undefined")}},另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。</dd>
</dl>

<h3 id="Description" name="Description">抛出异常</h3>

<p>如果 proto 参数不是 <code>null </code>或一个对象值,则抛出一个 {{jsxref("Global_Objects/TypeError", "TypeError")}} 异常。</p>

<h2 id="Examples" name="Examples">例子</h2>

<h4 id="使用Object.create实现类式继承">使用Object.create实现类式继承</h4>

<p>下面的例子演示了如何使用Object.create来实现类式继承。这是一个单继承。</p>

<div class="highlight">
<pre class="brush: js">
//Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); //call super constructor.
}

Rectangle.prototype = Object.create(Shape.prototype);

var rect = new Rectangle();

rect instanceof Rectangle //true.
rect instanceof Shape //true.

rect.move(1, 1); //Outputs, "Shape moved."
</pre>
</div>

<p>如果你希望能继承到多个对象,则可以使用<span class="short_text" id="result_box" lang="zh-CN"><span>混入的方式。</span></span></p>

<div class="highlight">
<pre class="brush: js">
function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); //inherit
mixin(MyClass.prototype, OtherSuperClass.prototype); //mixin

MyClass.prototype.myMethod = function() {
     // do a thing
};
</pre>
</div>

<p>mixin函数会把超类原型上的函数拷贝到子类原型上,这里mixin函数没有给出,需要由你实现。一个和 mixin 很像的函数是&nbsp;<span style="line-height:1.5">&nbsp;</span><a href="https://api.jquery.com/jQuery.extend/" style="line-height: 1.5;" title="https://api.jquery.com/jQuery.extend/">jQuery.extend</a>。</p>

<h4 id="使用Object.create_的_propertyObject_参数" style="line-height: 18px;">使用Object.create 的 propertyObject 参数</h4>

<pre class="brush: js" style="font-size: 14px;">
var o;

// 创建一个原型为null的空对象
o = Object.create(null);


o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);


o = Object.create(Object.prototype, {
  // foo会成为所创建对象的数据属性
  foo: { writable:true, configurable:true, value: "hello" },
  // bar会成为所创建对象的访问器属性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) { console.log("Setting `o.bar` to", value) }
}})


function Constructor(){}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype);
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码


// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })

// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
//"q"

delete o.p
//false

//创建一个可写的,可枚举的,可配置的属性p
o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });</pre>

<h3 id="Polyfill" style="line-height: 24px;">Polyfill</h3>

<p>这个polyfill只实现了创建一个指定原型的对象的功能,而不能同时添加特定的属性,也就是没有实现原生的Object.create函数中的第二个参数。</p>

<pre class="brush: js">
if (typeof Object.create != 'function') {
&nbsp;&nbsp;&nbsp; (function () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var F = function () {};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object.create = function (o) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (arguments.length &gt; 1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw Error('Second argument not supported');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (o === null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw Error('Cannot set a null [[Prototype]]');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (typeof o != 'object') {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw TypeError('Argument must be an object');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F.prototype = o;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new F();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp; })();
}</pre>

<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范版本</th>
   <th scope="col">规范状态</th>
   <th scope="col">注解</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.2.3.5', 'Object.create')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.8.5</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-object.create', 'Object.create')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>&nbsp;</td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<p>{{ CompatibilityTable() }}</p>

<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>5</td>
   <td>{{ CompatGeckoDesktop("2") }}</td>
   <td>9</td>
   <td>11.60</td>
   <td>5</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>Android</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{ CompatGeckoDesktop("2") }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatUnknown() }}</td>
   <td>11.50</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="See_also" name="See_also" style="margin-bottom: 20px; line-height: 30px;">相关链接</h2>

<ul>
 <li>{{jsxref("Object.defineProperty")}}</li>
 <li>{{jsxref("Object.defineProperties")}}</li>
 <li>{{jsxref("Object.prototype.isPrototypeOf")}}</li>
 <li>John Resig's post on&nbsp;<a class="external external-icon" href="https://ejohn.org/blog/objectgetprototypeof/" style="white-space: pre-line;" title="https://ejohn.org/blog/objectgetprototypeof/">getPrototypeOf</a></li>
</ul>
恢复到这个版本