面试题答案
一键面试- 利用函数构造函数实现简单继承结构:
// 父构造函数 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();
- 原型链在继承过程中的作用:
- 当我们访问
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
方法并执行。 - 这就是原型链的作用,它提供了一种机制,使得对象可以访问其原型对象上的属性和方法,从而实现继承。
- 当我们访问
- 不同对象的
__proto__
和prototype
之间的关系:- 构造函数:每个构造函数(如
Animal
和Dog
)都有一个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.prototype
的constructor
属性,使其正确指向Dog
构造函数。
- 构造函数:每个构造函数(如