JS中构造函数继承问题注意事项总结

在 JavaScript 中,继承是通过原型链来实现的。当你想要创建一个子类(比如 Student)继承一个父类(比如 Person)时,通常会使用 Object.create 来创建 Student 的原型对象。这背后有一些重要的原因:

1. 共享与独立性

当你执行 Student.prototype = Person.prototype 时,Student 的原型对象与 Person 的原型对象指向同一个对象。这意味着对 Student.prototype 的任何修改都会直接影响到 Person.prototype,反之亦然。这种共享可能会导致意外的副作用。

javascript 复制代码
function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function() {
    console.log("Hello, I'm " + this.name);
};

function Student(name, school) {
    Person.call(this, name);
    this.school = school;
}

// 错误示范:Student.prototype 和 Person.prototype 是同一个对象
Student.prototype = Person.prototype;

Student.prototype.sayHello = function() {
    console.log("Hi, I'm " + this.name + " from " + this.school);
};

const person = new Person("Alice");
person.sayHello(); // 现在会输出 "Hi, I'm Alice from undefined",而不是预期的 "Hello, I'm Alice"

如上所示,当你修改 Student.prototype.sayHello 时,Person.prototype.sayHello 也会被覆盖,因为它们指向同一个对象。这种行为通常是不希望发生的。

2. 保持独立的原型链

使用 Object.create 方法时,你会创建一个新对象,这个对象的原型指向 Person.prototype,而不是直接使用 Person.prototype。这样,Student.prototype 就是一个独立的对象了,它继承了 Person.prototype 的所有属性和方法,但对它的修改不会影响 Person.prototype

javascript 复制代码
function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function() {
    console.log("Hello, I'm " + this.name);
};

function Student(name, school) {
    Person.call(this, name);
    this.school = school;
}

// 推荐方法:使用 Object.create 创建独立的原型对象
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.sayHello = function() {
    console.log("Hi, I'm " + this.name + " from " + this.school);
};

const person = new Person("Alice");
person.sayHello(); // 输出: "Hello, I'm Alice"

const student = new Student("Bob", "XYZ University");
student.sayHello(); // 输出: "Hi, I'm Bob from XYZ University"

在这个例子中,Student.prototypePerson.prototype 的一个独立副本。Student.prototype 继承了 Person.prototype 的方法和属性,但对 Student.prototype 的任何修改不会影响 Person.prototype

3. 设置 constructor 属性

在使用 Object.create 时,Student.prototypeconstructor 属性会指向 Person,因为 Object.create(Person.prototype) 创建的对象继承了 Person.prototype。因此,你通常需要手动设置 Student.prototype.constructorStudent,以确保它指向正确的构造函数。

javascript 复制代码
Student.prototype.constructor = Student;

这一步虽然不是强制性的,但它可以确保 Student 的实例的 constructor 属性正确指向 Student 而不是 Person,这对于调试和代码的可读性很重要。

4. 总结

  • Object.create 的优势 :它创建了一个新对象,这个对象的原型指向 Person.prototype,使得 Student.prototypePerson.prototype 的独立副本。这样修改 Student.prototype 不会影响 Person.prototype
  • 避免副作用 :直接使用 Student.prototype = Person.prototype 会让两个构造函数的原型对象共享一个对象,导致修改其中一个时,另一个也会受到影响。
  • constructor 的设置 :使用 Object.create 之后,你需要手动将 constructor 指向 Student,以保持正确的构造函数引用。

使用 Object.create 是推荐的做法,因为它提供了更好的代码隔离和继承结构。

相关推荐
zhiSiBuYu05179 分钟前
重排序(Rerank)提升检索准确率实战指南
开发语言·python·算法
蜡台12 分钟前
Node 安装 awesome-qr 失败解决
javascript·vue·qrcode·awesome-qr
c++之路44 分钟前
C++跨平台(九):跨平台字节序统一处理
开发语言·arm开发·c++
Evand J1 小时前
【MATLAB例程|车联网6】考虑调头车流扰动与网联车辆实时感知信息的干线多交叉口 FAC-CV 全感应协调控制仿真与性能对比分析
开发语言·matlab·仿真·代码·车联网·智慧交通·车辆
云絮.1 小时前
数据库事务
java·开发语言·数据库
派葛穆1 小时前
Python-pip切换镜像源
开发语言·python·pip
Full Stack Developme1 小时前
Java 漏斗算法 及应用场景
java·开发语言·算法
阿里嘎多学长1 小时前
2026-07-03 GitHub 热点项目精选
开发语言·程序员·github·代码托管
xxie1237942 小时前
Python 闭包:函数嵌套的 “状态捕获” 机制
开发语言·python
骑士雄师2 小时前
java面试记录: sychonized 锁,熔断组件,分布式锁
java·开发语言·面试