寫在前面:本文內容主要根據慕課網雙越老師的付費課程“一天時間迅速准備前端面試 快速構建初級前端知識體系 ”進行編寫,主要是為了自己在面試前總結學習,歡迎留言指教。
本系列包括如下內容:
每一部分包括題目和知識點兩部分。
原型和原型鏈
題目
- 如何准確判斷一個變量是不是數組
- 手寫一個建議的jQuery,考慮插件和擴展性
- class的原型本質,如何理解
1. 如何准確判斷一個變量是不是數組
instanceof
2. 手寫一個建議的jQuery,考慮插件和擴展性
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector)
const length = result.length
for (let i = 0; i < length; i++) {
this[i] = result[i]
}
this.length = length
this.selector = selector
//類似於數組,其實是一個對象
}
get(index) {
return this[index]
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const element = this[i];
fn(element)
}
}
on(type, fn) {
return this.each(element => {
element.addEventListener(type, fn, false)
})
}
//擴展很多DOM API
}
//插件機制
jQuery.prototype.dialog = function (info) {
alert(info)
}
// 造輪子 復寫機制
class myjQuery extends jQuery {
constructor(selector){
super(selector)
}
//擴展自己的方法
addClass(className) {
}
style(data) {
}
}
- html 內容
- 使用
3. class的原型本質,如何理解
- 原型和原型鏈的圖示
- 屬性和方法的執行規則
詳見知識點3
知識點
1. class和繼承
class的使用
- constructor
- 屬性
- 方法
如下代碼進行舉例說明:
class Student {
// constructor
constructor(name, number) {
this.name = name //屬性
this.number = number //屬性
}
// 方法
sayHi() {
console.log(
// ``替代'',可以使用${}
`姓名 ${this.name}, 學號 ${this.number}`
)
}
}
繼承的使用
- extends
- super
- 擴展或重寫方法
如下代碼進行舉例說明:
//父類
class People {
constructor(name) {
this.name = name
}
eat(){
console.log(`${this.name} eat something`)
}
}
//子類
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi(){
console.log(`姓名 ${this.name} 學號 ${this.number}`)
}
}
class Teacher extends People{
constructor(name, major) {
super(name)
this.major = major
}
teach() {
console.log(`${this.name} 教授 ${this.major}`)
}
}
2. 類型判斷
instanceof
const a = ['Honda', 'Accord', 1998]
const b = '123'
console.log(a instanceof Array) //true
console.log(b instanceof Array) //false
3. 原型和原型鏈
首先,我們先分析一下在“繼承的使用”中創建的class的類型
// class 實際上是函數,可見是語法糖
typeof People // 'function'
typeof Student // 'function'
在了解了class其實是函數后,我們再了解一下隱式原型和顯示原型
// 隱式原型和顯示原型
console.log(xialuo.__proto__) //xialuo是Student的實例
console.log(Student.prototype)
console.log(xialuo.__proto__ === Student.prototype)
查看打印結果:
因此我們可以得到原型關系:
- 每個class都有顯式原型 prototype
- 每個實例都有隱式原型__proto__
- 實例的__proto__指向對應class的 prototype
可以得到下圖:
基於原型的執行規則:
- 獲取屬性xialuo.name或執行方法xialuo.sayHI()時
- 先在自身屬性和方法尋找
- 如果找不到則自動去__proto__尋找
接着,我們再次打印
console.log(Student.prototype.__proto__)
console.log(People.prototype) //People是Student的父類
console.log(Student.prototype.__proto__ === People.prototype)
因此我們可以得到如下的原型關系:
- 子類的prototype的__proto__指向其父類的prototype
可以得到下圖:
之后,我們再進一步
console.log(People.prototype.__proto__)
console.log(Object.prototype)
console.log(People.prototype.__proto__ === Object.prototype)
打印結果如下:
可以得到下圖: