返回创建实例对象的 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 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
constructor |
Chrome Full support 1 | Edge Full support 12 | Firefox Full support 1 | IE Full support 4 | Opera Full support Yes | Safari Full support Yes | WebView Android Full support 1 | Chrome Android Full support 18 | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support 1.0 | nodejs Full support Yes |
Legend
- Full support
- Full support