面试题答案
一键面试1. JavaScript 原型链基本概念
在 JavaScript 中,每个对象都有一个 [[Prototype]]
内部属性(在现代 JavaScript 中可以通过 __proto__
访问,虽然不推荐直接使用它,更推荐使用 Object.getPrototypeOf()
和 Object.setPrototypeOf()
方法),这个属性指向该对象的原型对象。原型对象自身也是一个对象,它也有自己的 [[Prototype]]
属性,这样就形成了一条链式结构,称为原型链。当访问一个对象的属性或方法时,如果该对象自身没有定义这个属性或方法,JavaScript 引擎就会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末尾(null
)。
2. 通过原型链实现属性和方法继承的示例
// 创建一个简单的构造函数
function Animal(name) {
this.name = name;
}
// 在 Animal 的原型上定义一个方法
Animal.prototype.speak = function() {
console.log(this.name +'makes a sound.');
};
// 创建一个 Dog 构造函数,继承自 Animal
function Dog(name, breed) {
// 调用 Animal 的构造函数,以初始化 name 属性
Animal.call(this, name);
this.breed = breed;
}
// 设置 Dog 的原型为 Animal 的实例,实现继承
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 在 Dog 的原型上定义一个方法
Dog.prototype.bark = function() {
console.log(this.name +'barks.');
};
// 创建一个 Dog 的实例
const myDog = new Dog('Buddy', 'Golden Retriever');
// 查找属性和方法的过程
// 1. 查找 myDog 对象自身是否有 name 属性,有,返回 'Buddy'
console.log(myDog.name);
// 2. 查找 myDog 对象自身是否有 speak 方法,没有,沿着原型链向上查找
// 找到 Animal.prototype.speak,执行该方法,输出 'Buddy makes a sound.'
myDog.speak();
// 3. 查找 myDog 对象自身是否有 bark 方法,有,执行该方法,输出 'Buddy barks.'
myDog.bark();
// 4. 查找 myDog 对象自身是否有 breed 属性,有,返回 'Golden Retriever'
console.log(myDog.breed);
在上述代码中:
Animal
是一个基础构造函数,它的原型Animal.prototype
定义了speak
方法。Dog
构造函数通过Object.create(Animal.prototype)
将其原型设置为Animal
的实例,从而继承了Animal
的属性和方法。myDog
是Dog
的实例,当访问myDog
的属性或方法时,JavaScript 引擎会按照原型链的顺序查找。如果myDog
自身有该属性或方法,则直接使用;如果没有,则沿着原型链向上查找,直到找到或到达原型链末尾。