【前端面試】JS中通過原型鏈和class語法分別實現類的繼承
阿新 • • 發佈:2021-02-10
技術標籤:javascript學習筆記前端面試javascriptjsclass類
【前端面試】JS中通過原型鏈和class語法分別實現類的繼承
JS中的
類
本質上是一個
function
型別的物件,這是JS的獨特之處。
原型鏈實現繼承
在ES6的class
語法推出之前,要實現類的繼承要通過修改原型鏈來實現:
- 首先定義一個父類,本質上是定義父類的建構函式,其對應的
Person.prototype
會自動被建立
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function(name) {
this.name = name
}
- 然後定義一個子類,通過在子類中用
call
函式,以子類的身份呼叫父類的建構函式,實現繼承父類的成員變數
function Student (name, age) {
Person.call(this,name,age)
}
這樣做還不夠,因為父類的成員函式
還沒有被繼承。可以通過將Student
的prototype
的原型鏈__proto__
指向Person
的prototype
,來實現這一功能。
Student.prototype = new Person //這裡無需入參,引數預設是undefined就行,
// 反正成員變數已經在前一步通過call繼承到子型別Student物件上了
// 如果需要呼叫Student的成員變數,也輪不到沿著原型鏈找到這個new Person頭上
然後試一下功能
const s1 = new Student('Bob', 23)
s1.setName('Tom')
console.log(s1)
看起來大功告成!
但是…還有一個細節沒有處理,那就是:Student.prototype.constructor
此刻還指向Person
,而正確的情況是:它應該指向Student本身,因此應該:
Student.prototype. constructor = Student
一個細節
在Student.prototype = new Person
這一步中,我提到了可以不帶引數,因為Student
物件本身就有name
和age
屬性,只不過是undefined
,因此不會沿著原型鏈找到new Person上。這裡做個簡單的測試。
Student.prototype = new Person('Jerry', 100) //改變Student原型鏈的時候帶入參
const student1 = new Student //新建student例項的時候不帶入參
console.log(student1.name) //undefined 而不是 Jerry
ES6 class 語法實現繼承
要實現和上面的程式碼一樣的邏輯,我們應該這麼做:
- 先定義父類Person
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
setName(newName) {
this.name = newName
}
}
然後定義子類Student,繼承父類Person
class Student extends Person{
constructor(name, age){
super(name, age)
}
}
測試一下:
const student1 = new Student('Tom', 24)
student1.setName('Jerry')
結果如下:
檢查繼承關係: