JavaScript中constructor属性的行为与修正

作者:木棉

时间:2026-10-24

浏览:160

本文解析JavaScript中constructor属性的核心机制,指出其始终指向创建对象的构造函数。重点探讨当直接覆盖prototype对象时,constructor会错误指向Object的问题,并给出通过手动重置Person.prototype.constructor来修复继承关系的标准方案。

文章目录

constructor属性的基本指向

constructor属性始终指向创建当前对象的构造函数。以下通过具体代码示例进行说明:


代码如下:

 
// 等价于 var foo = new Array(1, 56, 34, 12);
var arr = [1, 56, 34, 12];
console.log(arr.constructor === Array); // true
// 等价于 var foo = new Function();
var Foo = function() { };
console.log(Foo.constructor === Function); // true
// 由构造函数实例化一个obj对象
var obj = new Foo();
console.log(obj.constructor === Foo); // true
// 将上面两段代码合起来,就得到下面的结论
console.log(obj.constructor.constructor === Function); // true

prototype覆盖导致的问题

然而,当constructor与prototype结合使用时,会出现一些有趣的现象。


每个函数默认拥有一个prototype属性,该属性的constructor默认指向函数本身。示例如下:


代码如下:

 
function Person(name) {
this.name = name;
}; 
Person.prototype.getName = function() {
return this.name;
}; 
var p = new Person("ZhangSan");
console.log(p.constructor === Person); // true
console.log(Person.prototype.constructor === Person); // true
// 将上两行代码合并就得到如下结果
console.log(p.constructor.prototype.constructor === Person); // true

但是,当我们重新定义函数的prototype时(注意:此处是覆盖而非修改),constructor属性的行为会变得异常,如下示例所示:


代码如下:

 
function Person(name) {
this.name = name;
}; 
Person.prototype = {
getName: function() {
return this.name;
} 
}; 
var p = new Person("ZhangSan");
console.log(p.constructor === Person); // false
console.log(Person.prototype.constructor === Person); // false
console.log(p.constructor.prototype.constructor === Person); // false

造成这一现象的原因是什么?


实际上,覆盖Person.prototype等价于执行以下操作:


代码如下:

 
Person.prototype = new Object({
getName: function() {
return this.name;
} 
}); 

由于constructor属性始终指向创建自身的构造函数,此时Person.prototype.constructor实际上指向Object。即:


代码如下:

 
function Person(name) {
this.name = name;
}; 
Person.prototype = {
getName: function() {
return this.name;
} 
}; 
var p = new Person("ZhangSan");
console.log(p.constructor === Object); // true
console.log(Person.prototype.constructor === Object); // true
console.log(p.constructor.prototype.constructor === Object); // true

修正constructor指向的方法

如何修正这一问题?解决方法很简单,只需重新覆盖Person.prototype.constructor即可:


代码如下:

 
function Person(name) {
this.name = name;
}; 
Person.prototype = new Object({
getName: function() {
return this.name;
} 
}); 
Person.prototype.constructor = Person;
var p = new Person("ZhangSan");
console.log(p.constructor === Person); // true
console.log(Person.prototype.constructor === Person); // true
console.log(p.constructor.prototype.constructor === Person); // true

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章