前端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

posted @ 2021-07-11 12:39  Dreamup_lu  阅读(642)  评论(0编辑  收藏  举报