MST
星途 面试题库

面试题:JavaScript函数构造函数的原型链与继承

在JavaScript中,利用函数构造函数实现一个简单的继承结构,要求解释清楚原型链是如何在这个继承过程中起作用的,以及不同对象的 `__proto__` 和 `prototype` 之间的关系。
37.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 利用函数构造函数实现简单继承结构
    // 父构造函数
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.speak = function () {
        console.log(this.name +'makes a sound.');
    };
    
    // 子构造函数
    function Dog(name, breed) {
        // 调用父构造函数,将父构造函数的this绑定到子构造函数的实例上
        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();
    
  2. 原型链在继承过程中的作用
    • 当我们访问 myDog.speak() 时,JavaScript 首先在 myDog 的自身属性中查找 speak 方法,没有找到。
    • 然后它会沿着 myDog.__proto__ (也就是 Dog.prototype )查找,Dog.prototype 是通过 Object.create(Animal.prototype) 创建的,所以 Dog.prototype.__proto__ 指向 Animal.prototype
    • Dog.prototype 中也没有找到 speak 方法,就继续沿着 Dog.prototype.__proto__ (即 Animal.prototype )查找,最终找到了 speak 方法并执行。
    • 这就是原型链的作用,它提供了一种机制,使得对象可以访问其原型对象上的属性和方法,从而实现继承。
  3. 不同对象的 __proto__prototype 之间的关系
    • 构造函数:每个构造函数(如 AnimalDog )都有一个 prototype 属性。这个 prototype 属性是一个对象,它包含了希望被构造函数创建的实例共享的属性和方法。例如,Animal.prototype 包含了 speak 方法,Dog.prototype 经过修改后包含了 bark 方法以及从 Animal.prototype 继承来的属性和方法。
    • 实例对象:实例对象(如 myDog )有一个 __proto__ 属性,它指向构造函数的 prototype 对象。所以 myDog.__proto__ 指向 Dog.prototype ,而 Dog.prototype.__proto__ 又指向 Animal.prototype 。这种链式关系构成了原型链。
    • 当我们设置 Dog.prototype = Object.create(Animal.prototype) 时,实际上是创建了一个新的对象,这个对象的 __proto__ 指向 Animal.prototype ,然后将这个新对象赋值给 Dog.prototype ,这样 Dog 的实例(如 myDog )就可以通过原型链访问到 Animal 的属性和方法了。同时,通过 Dog.prototype.constructor = Dog 来修正 Dog.prototypeconstructor 属性,使其正确指向 Dog 构造函数。