前端面试手撕题【持续补充】

108 阅读2分钟

一、js手撕

实现一个判断具体数据类型的函数

   // Object.prototype.toString.call(null)返回'[object Null]'
   // 实现一个判断具体数据类型的函数:
   function checkType(val){
       return Object.prototype.toString.call(val).slice(8,-1).toLowerCase()
   }

手写深拷贝

    // 手写递归实现深拷贝
    function deepClone(obj){
        if(obj === null || typeof obj!= 'object')
            return obj
        const clone = Array.isArray(obj)? []: {}
        for(const key in obj){
            if(Object.hasOwnProperty.call(obj, key))
                clone[key] = deepCoppy(obj[key])
        }
        return clone
    }

手写防抖 和 节流

  • 防抖(回城):对于连续快速触发,只执行最后一次
    function debounce(fun, delay){
        let timer = null 
        return function(...args){
            if(timer)
                clearTimeout(timer)
            timer = setTimeout(()=>{
                fun.call(this, ...args)
            },delay)
        }
    }
    
  • 节流(技能冷却):在规定时间内不会重复触发回调,只有大于这个时间间隔才会触发
    function throttle(fun, delay){
        let timer = null
        return function(...args){
            if(!timer){
                timer = setTimeout(()=>{
                    fun.call(this, ...args)
                    timer = null
                },delay)
            }
        }
    }
    

手写原型继承、组合继承、寄生组合继承、ES6继承

原型继承 组合继承 寄生组合继承 ES6继承
缺点:属性和方法无法私有化 缺点:每次创建子类实例,都执行了两次父类构造函数 缺点:书写麻烦 缺点:无

function Animal(){}
Animal.prototype.eat = function(){
    console.log('eating')
}
function Dog(){}
Dog.prototype = new Animal()
Dog.prototype.bark = function(){
    console.log('barking')
}
const myDog = new Dog()
myDog.eat() // eating
myDog.bark() // barking



function Animal(name){
    this.name = name
}
Animal.prototype.eat = function(){
    console.log(`${this.name} is eating`)
}
function Dog(name, type){
    Animal.call(this, name)
    this.type = type
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
Dog.prototype.bark = function(){
    console.log(`${this.type} is barking`)
}
const myDog = new Dog('豆豆', '金毛')
myDog.eat() // 豆豆 is eating
myDog.bark() // 金毛 is barking



function Animal(name){
    this.name = name
}
Animal.prototype.eat = function(){
    console.log(`${this.name} is eating`)
}
function Dog(name, type){
    Animal.call(this, name)
    this.type = type
}
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
Dog.prototype.bark = function(){
    console.log(`${this.type} is barking`)
}
const myDog = new Dog('豆豆', '金毛')
myDog.eat() // 豆豆 is eating
myDog.bark() // 金毛 is barking



class Animal{
    constructor(name){
        this.name = name
    }
    eat(){
        console.log(`${this.name} is eating`)
    }
}
class Dog extends Animal{
    constructor(name, type){
        super(name)
        this.type = type
    }
    bark(){
        console.log(`${this.type} is barking`)
    }
}
const myDog = new Dog('豆豆', '金毛')
myDog.eat() // 豆豆 is eating
myDog.bark() // 金毛 is barking


手写发布订阅模式(观察者模式)

class Subject {
    constructor() {
        this.observers = []
    }
    addObserver(observer) {
        this.observers.push(observer)
    }
    removeObserver(observer) {
        const index = this.observers.indexOf(observer)
        if (index != -1) {
            this.observers.splice(index, 1)
        }
    }
    notify(data) {
        this.observers.forEach(observer => {
            observer.update(data, observer.name)
        })
    }
}
class Observer {
    constructor(name) {
        this.name = name
    }
    update(data, observer) {
        console.log(`Received data: ${data} ${observer}`)
    }
}
const sub = new Subject()
const obs1 = new Observer('observer1')
const obs2 = new Observer('observer2')
sub.addObserver(obs1)
sub.addObserver(obs2)
sub.notify('Hello')

手写Promise.all()串行

手写Promise.all()并行

手写Promise.race()

手写Promise.allSelected()

手写async和await

手写instanceof

手写数组扁平

手写数组去重

手写数组交集

手写数组并集

手写数组差集

手写new

手写call()

手写apply()

手写bind()

手写快排

手写二分查找

手写下划线转小驼峰 get_element_by_id -> getElementById

手写url转对象

回调函数实现循环打印红黄绿 红(2s) -> 黄(1s) -> 绿(3s)

promise实现循环打印红黄绿 红(2s) -> 黄(1s) -> 绿(3s)

async await实现循环打印红黄绿 红(2s) -> 黄(1s) -> 绿(3s)

遍历dom节点

对象数组转树

Promise应用场景手写题

二、判断输出