前端JS面試題-基礎-原型和原型鏈


寫在前面:本文內容主要根據慕課網雙越老師的付費課程“一天時間迅速准備前端面試 快速構建初級前端知識體系 ”進行編寫,主要是為了自己在面試前總結學習,歡迎留言指教。

本系列包括如下內容:

每一部分包括題目知識點兩部分。

原型和原型鏈

題目

  1. 如何准確判斷一個變量是不是數組
  2. 手寫一個建議的jQuery,考慮插件和擴展性
  3. 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 內容
    image
  • 使用
    image

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)

查看打印結果:
image
image

因此我們可以得到原型關系

  • 每個class都有顯式原型 prototype
  • 每個實例都有隱式原型__proto__
  • 實例的__proto__指向對應class的 prototype

可以得到下圖:
image

基於原型的執行規則

  • 獲取屬性xialuo.name或執行方法xialuo.sayHI()時
  • 先在自身屬性和方法尋找
  • 如果找不到則自動去__proto__尋找

接着,我們再次打印

console.log(Student.prototype.__proto__)
console.log(People.prototype) //People是Student的父類
console.log(Student.prototype.__proto__ === People.prototype)

image
image
image

因此我們可以得到如下的原型關系

  • 子類的prototype的__proto__指向其父類的prototype

可以得到下圖:
image

之后,我們再進一步

console.log(People.prototype.__proto__)
console.log(Object.prototype)
console.log(People.prototype.__proto__ === Object.prototype)

打印結果如下:
image
image
image

可以得到下圖:
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM