面试题答案
一键面试- 原型链查找属性的原理
- 在JavaScript中,每个对象都有一个
[[Prototype]]
内部属性(在现代JavaScript中可以通过__proto__
访问,不推荐直接使用,推荐使用Object.getPrototypeOf()
获取)。当访问对象的一个属性时,如果对象本身没有这个属性,JavaScript引擎会沿着[[Prototype]]
链向上查找,直到找到该属性或者到达原型链的顶端(null
)。 - 原型链是基于原型继承的概念。每个函数都有一个
prototype
属性,当使用new
关键字调用构造函数创建对象时,新创建的对象的[[Prototype]]
会指向构造函数的prototype
属性。
- 在JavaScript中,每个对象都有一个
- 代码示例
// 定义一个构造函数
function Animal() {
this.species = 'animal';
}
// 在Animal的原型上添加一个方法
Animal.prototype.getSpecies = function () {
return this.species;
};
// 定义一个Dog构造函数,继承自Animal
function Dog(name) {
this.name = name;
// 调用Animal构造函数来初始化species属性
Animal.call(this);
}
// 设置Dog的原型为Animal的实例,建立原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 创建一个Dog实例
const myDog = new Dog('Buddy');
// 访问myDog的属性
console.log(myDog.name); // 直接在myDog对象上找到name属性,输出:Buddy
console.log(myDog.species); // myDog对象本身没有species属性,沿着原型链在Animal.prototype上找到,输出:animal
console.log(myDog.getSpecies()); // myDog对象本身没有getSpecies方法,沿着原型链在Animal.prototype上找到,输出:animal
// 如果访问一个不存在的属性
console.log(myDog.age); // myDog本身没有age属性,沿着原型链查找也找不到,返回:undefined
在上述代码中:
myDog
是Dog
的实例,Dog.prototype
是Animal.prototype
的实例,形成了原型链myDog -> Dog.prototype -> Animal.prototype -> null
。- 当访问
myDog.name
时,由于myDog
对象自身有name
属性,直接返回'Buddy'
。 - 当访问
myDog.species
时,myDog
对象自身没有species
属性,JavaScript引擎沿着原型链到Dog.prototype
查找,Dog.prototype
也没有,继续到Animal.prototype
,在Animal.prototype
上找到了species
属性,返回'animal'
。 - 当调用
myDog.getSpecies()
时,myDog
对象自身没有getSpecies
方法,沿着原型链在Animal.prototype
上找到了该方法并执行,返回'animal'
。 - 当访问
myDog.age
时,沿着整个原型链都没有找到age
属性,所以返回undefined
。