手写函数
1.模拟call
Function.prototype.mycall = function(context = window, ...args){
    if(this == Function.prototype){
        return undefined;
    }
    context = context || window;
    const fn = Symbol();
    context[fn] = this;
    const result = context[fn](...args);
    delete context[fn]
    return result
}2.模拟apply
Function.prototype.myapply = function(context = window, args){
    if(this == Function.prototype){
        return undefined;
    }
    context = context || window;
    const fn = Symbol();
    context[fn] = this;
    if (Array.isArray(args)) {
        result = context[fn](...args);
    }else {
        result = context[fn]();
    }
    delete context[fn]
    return result
}3.手写防抖
function debounce(handleEvent, time, flag){
    let timeout = null;
    return function(...agrs){
        clearTimeout(timeout)
        if(flag && !timeout){
            handleEvent.apply(this, args)
        }
        timeout = setTimeout(()=>{
            handleEvent.apply(this, args)
        },time)
    }
}4.手写节流
function throttle(handleEvent, time){
    let timer = null;
    return function(...args){
        if(!timer){
            timer = setTimeout(() => {
                timer = null;
                handleEvent.apply(this, args)
            }, time);
        }
    }
}5.手写深克隆
function copy(data){
    let obj = data instanceof Array ? [] : {}
    for (const [k,v] of Object.entries(data)) {
        obj[k] = typeof v == "object" ? copy(v) : v;
    }
    return obj
}6.手写数组去重
const unique = (array)=>{
    let container = {}
    return array.filter((item)=>{
        return container.hasOwnProperty(item) ? false : (container[item] = true);
    })
}7.手动实现ES5的继承
function People() {
    this.type = 'prople'
  }
People.prototype.eat = function () {
    console.log('吃东西啦');
}
function Man(name) {
    this.name = name;
    this.color = 'black';
}No.1原型继承
Man.prototype = new People();
let a = new Man()
console.log(a.__proto__)No.2构造函数继承
function Man(name){
    People.call(this)
}No.3组合继承
function Man(name){
    People.call(this)
}
Man.prototype = People.prototypeNo.4寄生组合继承
function Man(name){
    People.call(this)
}
Man.prototype = Object.create(People.prototype, {
    constructor: {
        value: Man
    }
})8.手动实现一个instanceof
function myinstanceof(target, origin){
    let proto = target.__proto__
    if(proto){
        if(proto === origin.prototype){
            return true
        }else{
            return myinstanceof(proto, origin)
        }
    }else{
        return false
    }
}9.手动实现一个Ajax
function myAjax(config){
    let {
        url,
        method = 'get',
        data = {},
        async = true,
        success,
        fail
    } = config
    let xml = new XMLHttpRequest()
    xml.onreadystatechange = function(){
        if(xml.readyState == 4){
            if((xml.status >= 200 && xml.status < 300) && xml.status == 304){
                const response = xml.responseText;
                success(response)
            }else{
                const error = xml.status
                fail(error)
            }
        }
    }
    xml.open(method, url, async)
    xml.send(data)
}10.基于Promise封装一个Ajax
function promiseAjax(config){
    let {
        url,
        method = 'get',
        data = {},
        async = true,
        success,
        fail
    } = config
    return new Promise((resolve, reject)=>{
        let xml = new XMLHttpRequest();
        xml.open(method, url, async)
        xml.send(data)
        xml.onreadystatechange = function() {
            if(xml.readyState == 4){
                if((xml.status >= 200 && xml.status < 300) && xml.status == 304){
                    const response = xml.responseText
                    resolve(response)
                }else{
                    const error = xml.status
                    reject(error)
                }
            }
        }
        xml.onerror = function(){
            reject(new TypeError("请求出错"))
        }
        xml.timeout = function(){
            reject(new TypeError("请求超时"))
        }
    })
}11.实现一个单例设计模式
class Unit{
    static getInstance(){
        if(!this.instance){
            this.instance = new Unit()
        }
        return this.instance
    }
}12.图片懒加载
let imgs = document.getElementsByTagName("img");
let n = 0
lazyload()
//节流函数
function throttle(handleEvent,time){
    let timer
    return function(...args){
        if(timer){
            timer = setTimeout(() => {
                timer = null
                handleEvent.apply(this,args)
            }, time);
        }
    }
}
function lazyload(){
    let seeHight = window.innerHeight
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    for(let i = n; i < imgs.length; i++){
        if(imgs[i].offsetTop < seeHight + scrollTop){
            if(imgs[i].getAttribute('src') == 'loading.gif'){
                imgs[i].src = imgs[i].getAttribute('data-src');
            }
            n = i + 1;
        }
    }
}
window.addEventListener('scroll',throttle())13.JS实现LRU算法
class LRUCache{
    constructor(capacity){
        this.capacity = capacity;
        this.cache = new Map();
    }
    get(key){
        //如果没有,返回-1
        if(!this.cache.has(key)) return -1;
        const value = this.cache.get(key);
        this.cache.delete(key);
        this.cache.set(key,value)
        return value
    }
    set(key,value){
        if(this.cache.has(key)){
            this.cache.delete(key)
        }else{
            if(this.cache.size == this.capacity){
                const delKey = this.cache.keys().next().value;
                this.cache.delete(delKey)
            }
        }
        this.cache.set(key,value)
    }
}