MST

星途 面试题库

面试题:JavaScript中原型链与继承机制基础理解

请描述JavaScript中构造函数、原型对象、实例之间的关系,并举例说明如何通过原型链实现继承。
32.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

构造函数、原型对象、实例之间的关系

  1. 构造函数:在JavaScript中,构造函数是用于创建对象的函数。当使用 new 关键字调用构造函数时,会创建一个新的对象实例。构造函数内部通过 this 关键字来引用新创建的实例对象,并可以为其添加属性和方法。例如:
function Person(name, age) {
    this.name = name;
    this.age = age;
}
  1. 原型对象:每个函数都有一个 prototype 属性,该属性指向一个对象,这个对象就是原型对象。原型对象的作用是为通过该构造函数创建的所有实例对象共享属性和方法。当访问实例对象的属性或方法时,如果实例对象本身没有该属性或方法,JavaScript会沿着原型链查找原型对象上是否存在该属性或方法。例如,上面 Person 构造函数的原型对象可以添加方法:
Person.prototype.sayHello = function() {
    console.log(`Hello, I'm ${this.name} and I'm ${this.age} years old.`);
};
  1. 实例:通过使用 new 关键字调用构造函数创建的对象就是实例。实例对象可以访问构造函数内部定义的属性,也可以访问原型对象上定义的属性和方法。例如:
const person1 = new Person('John', 30);
person1.sayHello(); 

实例对象有一个 __proto__ 属性,它指向构造函数的原型对象。这就建立了实例与原型对象之间的联系,多个实例对象共享原型对象上的属性和方法,从而节省内存。

通过原型链实现继承

  1. 经典继承方式
// 父构造函数
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function() {
    console.log(this.name + ' makes a sound.');
};

// 子构造函数
function Dog(name, breed) {
    // 借用父构造函数初始化属性
    Animal.call(this, name);
    this.breed = breed;
}

// 设置原型链,实现继承
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 为子构造函数的原型添加新方法
Dog.prototype.bark = function() {
    console.log(this.name + ' barks.');
};

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); 
myDog.bark(); 

在上述代码中:

  • 通过 Animal.call(this, name)Dog 构造函数内部调用 Animal 构造函数,这样 Dog 实例就拥有了 Animal 构造函数定义的属性。
  • 使用 Object.create(Animal.prototype) 创建一个新对象,该对象的原型是 Animal.prototype,然后将其赋值给 Dog.prototype,从而建立了 Dog 实例到 Animal 原型对象的原型链。
  • 由于修改了 Dog.prototype,需要重新设置 Dog.prototype.constructorDog,以确保构造函数的引用正确。
  1. ES6 类继承方式
class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        console.log(this.name + ' makes a sound.');
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
    bark() {
        console.log(this.name + ' barks.');
    }
}

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); 
myDog.bark(); 

在ES6 类继承中:

  • class 关键字定义类,extends 关键字实现继承。
  • Dog 构造函数中,super(name) 调用父类 Animal 的构造函数,以初始化从父类继承的属性。
  • Dog 类可以直接定义新方法,如 bark,同时也继承了 Animal 类的方法,如 speak