JavaScript中constructor与prototype的关系及继承修复
本文详细解析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); // trueJS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
