前端常见手写面试题(持续更新中)

本文汇总了前端面试中常见的手写题,包括简单路由、forEach、观察者模式、apply方法、async/await原理、数据去重、map、redux-thunk、模板字符串解析、filter、new过程、every、findIndex、发布订阅模式、reduce、Array.of、compose函数及数组去重等多种方法和模式的实现,帮助开发者深入理解JavaScript核心概念。
摘要由CSDN通过智能技术生成

实现简单路由

// hash路由
class Route{
   
  constructor(){
   
    // 路由存储对象
    this.routes = {
   }
    // 当前hash
    this.currentHash = ''
    // 绑定this,避免监听时this指向改变
    this.freshRoute = this.freshRoute.bind(this)
    // 监听
    window.addEventListener('load', this.freshRoute, false)
    window.addEventListener('hashchange', this.freshRoute, false)
  }
  // 存储
  storeRoute (path, cb) {
   
    this.routes[path] = cb || function () {
   }
  }
  // 更新
  freshRoute () {
   
    this.currentHash = location.hash.slice(1) || '/'
    this.routes[this.currentHash]()
  }
}

实现forEach方法

Array.prototype.myForEach = function(callback, context=window) {
   
  // this=>arr
  let self = this,  
      i = 0,
      len = self.length;

  for(;i<len;i++) {
   
    typeof callback == 'function' && callback.call(context,self[i], i)
   }
}

实现观察者模式

观察者模式(基于发布订阅模式) 有观察者,也有被观察者

观察者需要放到被观察者中,被观察者的状态变化需要通知观察者 我变化了 内部也是基于发布订阅模式,收集观察者,状态变化后要主动通知观察者

class Subject {
    // 被观察者 学生
  constructor(name) {
   
    this.state = 'happy'
    this.observers = []; // 存储所有的观察者
  }
  // 收集所有的观察者
  attach(o){
    // Subject. prototype. attch
    this.observers.push(o)
  }
  // 更新被观察者 状态的方法
  setState(newState) {
   
    this.state = newState; // 更新状态
    // this 指被观察者 学生
    this.observers.forEach(o => o.update(this)) // 通知观察者 更新它们的状态
  }
}

class Observer{
    // 观察者 父母和老师
  constructor(name) {
   
    this.name = name
  }
  update(student) {
   
    console.log('当前' + this.name + '被通知了', '当前学生的状态是' + student.state)
  }
}

let student = new Subject('学生'); 

let parent = new Observer('父母'); 
let teacher = new Observer('老师'); 

// 被观察者存储观察者的前提,需要先接纳观察者
student. attach(parent); 
student. attach(teacher); 
student. setState('被欺负了');

实现apply方法

思路: 利用this的上下文特性。apply其实就是改一下参数的问题

Function.prototype.myApply = function(context = window, args) {
   
  // this-->func  context--> obj  args--> 传递过来的参数

  // 在context上加一个唯一值不影响context上的属性
  let key = Symbol('key')
  context[key] = this; // context为调用的上下文,this此处为函数,将这个函数作为context的方法
  // let args = [...arguments].slice(1)   //第一个参数为obj所以删除,伪数组转为数组

  let result = context[key](...args); // 这里和call传参不一样

  // 清除定义的this 不删除会导致context属性越来越多
  delete context[key]; 

  // 返回结果
  return result;
}
// 使用
function f(a,b){
   
 console.log(a,b)
 console.log(this.name)
}
let obj={
   
 name:'张三'
}
f.myApply(obj,[1,2])  //arguments[1]

基于Generator函数实现async/await原理

核心:传递给我一个Generator函数,把函数中的内容基于Iterator迭代器的特点一步步的执行

function readFile(file) {
   
    return new Promise(resolve => {
   
        setTimeout(() => {
   
            resolve(file);
    }, 1000);
    })
};

function asyncFunc(generator) {
   
    const iterator = generator(); // 接下来要执行next
  // data为第一次执行之后的返回结果,用于传给第二次执行
  const next = (data) => {
   
        let {
    value, done } = iterator.next(data); // 第二次执行,并接收第一次的请求结果 data

    if (done) return; // 执行完毕(到第三次)直接返回
    // 第一次执行next时,yield返回的 promise实例 赋值给了 value
    value
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值