JavaScript中constructor与prototype的关系及继承修复

作者:纸飞机时间:2026-10-28 08:51:38浏览:320

本文详细解析JavaScript中constructor与prototype属性的内在联系。通过对比原始值与对象包装类的类型差异,阐明构造函数返回对象的机制。重点讲解利用prototype实现继承时,直接赋值会导致constructor指向错误的常见问题,并提供通过手动指定constructor属性来修复原型链的标准解决方案。

constructor属性的定义与内置类型

一、constructor constructor属性的值是一个函数。在JavaScript中,除了null和undefined之外的所有类型的值、数组、函数以及对象,都拥有constructor属性,该属性的值指向创建当前实例的构造函数。例如:

代码如下:

var a = 12, // 数字
b = 'str', // 字符串
c = false, // 布尔值
d = [1, 'd', function() { return 5; }], // 数组
e = { name: 'e' }, // 对象
f = function() { return 'function'; }; // 函数
console.log('a: ', a.constructor); // Number()
console.log('b: ', b.constructor); // String()
console.log('c: ', c.constructor); // Boolean()
console.log('d: ', d.constructor); // Array()
console.log('e: ', e.constructor); // Object()
console.log('f: ', f.constructor); // Function()

上述示例中的构造函数均为JavaScript内置类型。开发者也可以自定义构造函数,例如:

代码如下:

function A(name) {
this.name = name;
}
var a = new A('a');
console.log(a.constructor); // A(name)

在调用构造函数时,必须使用new关键字。构造函数执行后返回的是一个对象实例,具体区别如下代码所示:

代码如下:

var a = 4;
var b = new Number(4);
console.log('a: ', typeof a); // a: number
console.log('b: ', typeof b); // b: object

prototype属性与原型链继承修复

二、 prototype prototype是函数对象的一个属性。默认情况下,函数的prototype属性值是一个与该函数同名的空对象;对于匿名函数,其prototype属性名通常指向Object。例如:

代码如下:

function fn() {}
console.log(fn.prototype); // fn { }

prototype属性的主要用途是实现JavaScript中的继承机制,示例如下:

代码如下:

function A(name) {
this.name = name;
}
A.prototype.show = function() {
console.log(this.name);
};
function B(name) {
this.name = name;
}
B.prototype = A.prototype;
var test = new B('test');
test.show(); // test

这里存在一个问题:实例test的constructor属性实际上指向的是A函数,而非B函数:

代码如下:

console.log(test.constructor); // A(name)


造成这一现象的原因是执行B.prototype = A.prototype时,将B.prototype的constructor属性覆盖为了A。因此,需要手动还原B.prototype的constructor属性:


代码如下:

function A(name) {
this.name = name;
}
A.prototype.show = function() {
console.log(this.name);
};
function B(name) {
this.name = name;
}
B.prototype = A.prototype;
B.prototype.constructor = B;
var test = new B('test');
test.show(); // test
console.log(test.constructor); // B(name)

之所以需要这样做,是因为prototype的值是一个对象,且该对象的constructor属性值即为其所在的函数。验证关系如下:

代码如下:

console.log(A.prototype.constructor === A); // true

作者最新文章