返回创建实例对象的 `Object` 构造函数的引用。注意，此属性的值是对函数本身的引用，而不是一个包含函数名称的字符串。对原始类型来说，如`1`，`true`和`"test"`，该值只可读。

## 描述

所有对象都会从它的原型上继承一个 `constructor` 属性：

    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

## 示例

### 打印一个对象的构造函数

以下示例创建一个原型，`Tree`，以及该类型的对象，即`theTree`。 然后打印`theTree`对象的`constructor`属性。

    function Tree(name) {
       this.name = name;
    }

    var theTree = new Tree("Redwood");
    console.log( "theTree.constructor is " + theTree.constructor );

打印输出：

    theTree.constructor is function Tree(name) {
        this.name = name;
    }

### 改变对象的 constructor

下面的例子展示了如何修改基本类型对象的 `constructor` 属性的值。只有 `true`, `1` 和 `"test"` 的不受影响，因为创建他们的是只读的原生构造函数（native constructors）。这个例子也说明了依赖一个对象的 `constructor` 属性并不安全。

    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") );

此示例显示以下输出：

    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

### 改变函数的 constructor

大多数情况下，此属性用于定义一个构造函数，并使用new和继承原型链进一步调用它。

    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

但为什么我们需要在这里执行最后一行？很不幸正确答案是 - 看情况而定。

让我们尝试定义在哪些情况下重新分配原始构造函数将起主要作用，何时它将是一个额外的未使用的代码行。

试想下一种情况：该对象具有创建自身的create方法。

    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

在上面的示例中，将显示异常，因为构造函数链接到Parent。

为了避免它，只需分配您将要使用的必要构造函数。

    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

好的，现在很清楚为什么更改构造函数会很有用。

让我们再考虑一个案例。

    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
      }
    };

对于此示例，我们需要保持父构造函数继续正常工作。

总结：手动设置或更新构造函数可能会导致不同且有时令人困惑的后果。为了防止它，只需在每个特定情况下定义构造函数的角色。在大多数情况下，不使用构造函数，并且不需要重新分配构造函数。

## 规范

Specification | Status | Comment
--- | --- | ---
ECMAScript 1st Edition (ECMA-262) | Standard | Initial definition. Implemented in JavaScript 1.1.
ECMAScript 5.1 (ECMA-262) Object.prototype.constructor | Standard |
ECMAScript 2015 (6th Edition, ECMA-262) Object.prototype.constructor | Standard |
ECMAScript Latest Draft (ECMA-262) Object.prototype.constructor | Draft |

## 浏览器兼容

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
`constructor` | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 1 | IE Full support Yes | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes

### Legend

Full support
  Full support