如果面試官問:請(qǐng)解釋下原型鏈的工作原理。然后你咋說?
1. 解釋原型鏈的工作原理
原型鏈?zhǔn)荍avaScript中實(shí)現(xiàn)繼承和查找屬性的一種機(jī)制。
在JavaScript中,每個(gè)函數(shù)都有一個(gè)prototype屬性,它指向一個(gè)對(duì)象,這個(gè)對(duì)象包含可以被該函數(shù)實(shí)例共享的屬性和方法。
當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),該對(duì)象會(huì)從它的構(gòu)造函數(shù)那里繼承prototype對(duì)象。
當(dāng)嘗試訪問一個(gè)對(duì)象的某個(gè)屬性或者方法時(shí),如果該對(duì)象本身沒有這個(gè)屬性或方法,JavaScript引擎會(huì)沿著原型鏈向上查找,直到找到這個(gè)屬性或方法為止。
如果在整個(gè)原型鏈上都沒有找到,則認(rèn)為該屬性或方法不存在。
1.1. 原型鏈工作原理的一個(gè)簡要概述:
對(duì)象與原型:
- 每個(gè)對(duì)象都有一個(gè)內(nèi)部鏈接[[Prototype]],指向它的原型對(duì)象。
- 普通對(duì)象的原型通常是Object.prototype。
- 函數(shù)對(duì)象也有一個(gè)prototype屬性,用于作為其構(gòu)造函數(shù)創(chuàng)建的對(duì)象的原型。
構(gòu)造函數(shù)與原型:
- 構(gòu)造函數(shù)創(chuàng)建的對(duì)象會(huì)繼承該構(gòu)造函數(shù)的prototype對(duì)象。
- 構(gòu)造函數(shù)的prototype對(duì)象通常包含一些共享的方法和屬性。
原型鏈的查找:
- 當(dāng)訪問一個(gè)對(duì)象的屬性或方法時(shí),如果該對(duì)象自身沒有這個(gè)屬性或方法,則JavaScript引擎會(huì)查找該對(duì)象的[[Prototype]]。
- 如果在[[Prototype]]中也沒有找到,則繼續(xù)沿著[[Prototype]]鏈向上查找。
- 查找過程一直持續(xù)到Object.prototype,這是原型鏈的終點(diǎn),其[[Prototype]]值為null。
1.2. 一個(gè)簡單的示例來說明原型鏈的運(yùn)作方式:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, ' + this.name);
};
function Student(name, grade) {
Person.call(this, name); // 調(diào)用父類構(gòu)造函數(shù)
this.grade = grade;
}
// 設(shè)置Student的原型為Person的實(shí)例
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student; // 修復(fù)constructor指向
Student.prototype.study = function(subject) {
console.log(this.name + ' is studying ' + subject);
};
const student1 = new Student('Alice', 10);
console.log(student1.name); // "Alice"
student1.sayHello(); // "Hello, Alice"
student1.study('Math'); // "Alice is studying Math"
在這個(gè)例子中:
- Person構(gòu)造函數(shù)定義了一個(gè)sayHello方法。
- Student構(gòu)造函數(shù)繼承自Person。
- Student還添加了自己的study方法。
- 創(chuàng)建了一個(gè)Student實(shí)例student1。
當(dāng)我們?cè)L問student1的name屬性時(shí),它直接存在于student1對(duì)象中。
但是當(dāng)我們調(diào)用sayHello方法時(shí),這個(gè)方法不在student1對(duì)象中,因此會(huì)沿著原型鏈查找,并最終在Person.prototype中找到。
這就是原型鏈的基本工作原理。
通過這種方式,JavaScript實(shí)現(xiàn)了基于原型的繼承機(jī)制。