1. 程式人生 > 其它 >【前端面試】JS中通過原型鏈和class語法分別實現類的繼承

【前端面試】JS中通過原型鏈和class語法分別實現類的繼承

技術標籤: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)
}

這樣做還不夠,因為父類的成員函式還沒有被繼承。可以通過將Studentprototype的原型鏈__proto__指向Personprototype,來實現這一功能。

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物件本身就有nameage屬性,只不過是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')

結果如下:
在這裡插入圖片描述
檢查繼承關係:
在這裡插入圖片描述