JavaScript中constructor属性的行为与修正
本文解析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); // trueJavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
