一天时间迅速准备前端面试|JS基础—原型和原型链【三座大山之一,必考】
六年代码两茫茫,不思量,自难忘
6年资深前端主管一枚,只分享技术干货,项目实战经验,面试指导
关注博主不迷路~
本系列文章是博主精心整理的面试热点问题,吸收了大量的技术博客与面试文章,总结多年的面试经历,带你快速建立前端面试知识体系。抓住每一场面试的机会,知己知彼才能百战百胜。
希望各位同学收藏起来哦!!
- 上期回顾 JS基础–变量类型和计算
- 本系列订阅 面试指导专栏
文章目录
- 本期介绍
- 主要内容
- 关键字
- 如何用 class 实现继承
- class
- 继承
- 如何理解 JS 原型(隐式原型和显示原型)
- instanceof 是基于原型链实现的
- JS 原型相关的面试题
本期介绍
本期介绍原型、原型链和 class。包括 class ,继承,原型,原型链,instanceof。原型是 “JS 三座大山” 之一,原型和原型链也是必考知识点。
主要内容
- 如何用 class 实现继承
- 如何理解 JS 原型(隐式原型和显示原型)
- instanceof 是基于原型链实现的
- JS 原型相关的面试题
关键字
- 原型
- 原型链
- instanceof
- class
- 继承
如何用 class 实现继承
//语法结构
class 首字母大写 {
//构建
constructor(参数1,参数2){
}
}
class
class的本质仍然是函数(其实是ES6的语法糖)
- constructor
- 属性
- 方法
继承
es6的继承本质上是原型链 + 盗用构造函数
- extends(继承)
- super(执行父类构造函数)
- 扩展或重写方法
- class是面向对象的一个语法的实现
- class相当于一个模板,可以通过这个模板去构建一些东西,用constructor构建器构建
- 可以用constructor去复制他的属性和方法
如何理解 JS 原型(隐式原型和显示原型)
-
JS原型
每个class都有显式原型 prototype
每个class实例化后都有隐式原型 proto
实例的隐式原型指向对应class的显式原型 -
instanceof可以判断引用类型
比如Object是People的父类,People是Student的父类 -
class类具有定义的属性和方法,也有显示原型prototype,而将这个class类实例化就有了隐式原型_proto_,也就是 Shilihua.proto === Student.prototype
此原型图解可对照上面class 实现继承定义的类理解
instanceof 是基于原型链实现的
原型链:
- 每个构造函数都有 prototype(显式原型)
- 每个实例对象都有 proto / [[prototype]](隐式原型)
- 实例对象的__proto__ (隐式原型) 指向构造函数的 prototype(显式原型)
执行规则:
- 获取实例对象的属性或方法时
- 先在自身属性和方法寻找
- 若找不到则自动通过原型链一层一层向上查找
此原型链图解可对照上面class 实现继承定义的类理解
class People {
eat() {}
}
class Student extends People {
sayHi() {}
}
const xialuo = new Student(name, number);
// 实例对象隐式原型指向构造函数显式原型
xiaoluo.__proto__ === Student.prototype // true
Student.prototype.__proto__ === People.prototype // true
People.prototype.__proto__ === Object.prototype // true
// Object原型对象的隐式原型为null 所以null即原型链的顶端
Object.prototype.__proto__ === null // true
// 原型链
xiaoluo.__proto__ ->
Student.prototype.__proto__ ->
People.prototype.__proto__ ->
Object_prototype.__proto__ ->
null
instanceof:
- 是基于原型链实现的
- 用于检测构造函数的显式原型是否出现在某个实例对象的原型链上
JS 原型相关的面试题
- 如何判断一个变量是不是数组?
使用instanceof/Array.isArray方法
- 手写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 elem = this[i]
fn(elem)
}
}
on(type, fn) {
return this.each(elem => {
elem.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) {
}
}
// const $p = new jQuery('p')
// $p.get(1)
// $p.each((elem) => console.log(elem.nodeName))
// $p.on('click', () => alert('clicked'))
插件机制就是用 prototype 来对原型进行补充加强
造轮子就是用 extends 继承,然后新建自己的新方法
✨原 创 不 易 , 还 希 望 各 位 支 持
👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力
⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向
✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富