前端面试题视频讲解
实现类的继承
类的继承在几年前是重点内容,有n种继承方式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深入理解的去看红宝书即可,我们目前只实现一种最理想的继承方式。
function Parent(name) {
this.parent = name
}
Parent.prototype.say = function() {
console.log(`${
this.parent}: 你打篮球的样子像kunkun`)
}
function Child(name, parent) {
// 将父类的构造函数绑定在子类上
Parent.call(this, parent)
this.child = name
}
/** 1. 这一步不用Child.prototype =Parent.prototype的原因是怕共享内存,修改父类原型对象就会影响子类 2. 不用Child.prototype = new Parent()的原因是会调用2次父类的构造方法(另一次是call),会存在一份多余的父类实例属性3. Object.create是创建了父类原型的副本,与父类原型完全隔离*/
Child.prototype = Object.create(Parent.prototype);
Child.prototype.say = function() {
console.log(`${
this.parent}好,我是练习时长两年半的${
this.child}`);
}
// 注意记得把子类的构造指向子类本身
Child.prototype.constructor = Child;
var parent = new Parent('father');
parent.say() // father: 你打篮球的样子像kunkun
var child = new Child('cxk', 'father');
child.say() // father好,我是练习时长两年半的cxk
复制代码
instanceof
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。
const myInstanceof = (left, right) => {
// 基本数据类型都返回false
if (typeof left !== 'object' || left === null) return false;
let proto = Object.getPrototypeOf(left);
while (true) {
if (proto === null) return false;
if (proto === right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
复制代码
实现发布-订阅模式
class EventCenter{
// 1. 定义事件容器,用来装事件数组
let handlers = {
}
// 2. 添加事件方法,参数:事件名 事件方法
addEventListener(type, handler) {
// 创建新数组容器
if (!this.handlers[type]) {
this.handlers[type] = []
}
// 存入事件
this.handlers[type].push(handler)
}
// 3. 触发事件,参数:事件名 事件参数
dispatchEvent(type, params) {
// 若没有注册该事件则抛出错误
if (!this.handlers[type]) {
return new Error('该事件未注册')
}
// 触发事件
this.handlers[type].forEach(handler => {
handler(...params)
})
}
// 4. 事件移除,参数:事件名 要删除事件,若无第二个参数则删除该事件的订阅和发布
removeEventListener(type, handler) {
if (!this.handlers[type]) {
return new Error('事件无效')
}
if (!handler) {
// 移除事件
delete this.handlers[type]
} else {
const index = this.handlers[type].findIndex(el => el === handler)
if (index === -1) {
return new Error('无该绑定事件')
}
// 移除事件
this.handlers[type].splice(index, 1)
if (this.handlers[type].length === 0) {
delete this.handlers[type]
}
}
}
}
复制代码
throttle(节流)
高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。
const throttle = (fn, time) => {
let flag = true;
return function(