面试笔试

86 阅读1分钟

1. 防抖

function debounce(fn, delay) {
    return function() {
        let timer = null;
            if(timer !== null) {
            clearTimeout(timer);
        }

        timer = setTimeout(() => {
            fn.apply(this, arguments);
        }, delay)
    }
}
  

2. 节流

function throttle(fn, delay) {
    let timer = null;
    let startTime = Date.now();
    
    return function () {
        let currentTime = Date.now();
        let remaining = delay - (currentTime - startTime);
        clearTimeout(timer);
        if(remaining < 0) {
            fn.apply(this, arguments);
            
            startTime = Date.now();
        } else {
            timer = setTimeout(() => {
                fn();
            }, remaining)
        }
    }
}

3. 观察者模式

class Observer() {
    update(...data) {
        console.log('更新')
    }
}

class Subject() {
    constructor() {
        this.observerList = [];
    }
    
    add(observerName) {
        this.observerList.push(observerName)
        // 去重
        this.observerList = [... new Set(observerList)]
    },
    
    remove(observerName) {
        this.observerList = this.observerList.filter(item => item !== observerName)
    },
    
    notify(...data) {
        this.observerList.map(item => item.update(...data));
    }
}

4. 柯里化函数

function curry(fn) {
    function curried (...args) {
        if(args.length > fn.length) {
            fn.apply(this,args);
        } else {
            return function(...nextArgs) {
                return curried.apply(this, args.concat(nextArgs));
            }
        }
    }
}

5. Event-on实现

class EventBus () {
    constructor() {
        this.events = {}
    }
    
    on(eventName, callback) {
        if(!this.events[eventName]) {
            this.events[eventName] = []
        }
        
        this.events[eventName].push(callback);
    }
    
    emit(eventName, data) {
        let eventName = this.events[eventName];
        if(eventName) {
            eventName.forEach(cb => {
                cb(data)
            })
        }
    }
    
    
    off(eventName, callback) {
        this.events[eventName] = this.events[eventName].filter(cb => cb !== callback)
    }
}

6. jsonp实现

function jsonp(url, callbackParam='callback') {
    return new Promise((resolve, reject) => {
        let callbackName = 'jsonpCallback' + Date.now();
        window[callbackName] = function(data) {
            delete window[callbackName];
            resolve(data)
        }
        
        
        let script = document.createElement('script');
        script.src = `${url}${url.includes('?') ? '&' : '?'}${callbackName}='jsonpCallback'`
        
        script.onerror = function () {
            delete window[callbackName];
            reject('err')
        }
        document.body.appendChild(script);
    })
}

7. promise.all

function.protoType.all = function(promises) {
    let len = promises.length;
    let result = [];
    let count = 0;
    return new Promise((resolve, reject) => {
        for(let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(res => {
                count++;
                result[i] = res;
                
                if(count === len){
                   resolve(result);
                }
            }.catch(err => {
                reject(err);
            }))
        })
    }
}

8. promise.race

Promise.race = function(promises) {
    return new Promise((resolve, reject) => {
        for(let i = 0; i < promises.length; i++) {
            Promise.resolve(promises[i]).then(res => {
                resolve(res);
            }.catch(err=> {
                reject(err);
            }))
        }
    })
}

9.深拷贝

function deepClone(obj) {
    if(obj === null || typeof obj !== 'object') {
        return;
    }

    let result = Array.isArray(obj) ? [] : {};
    
    for(let key in obj) {
        if(obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key]);
        }
    }
    
    return result;
}

10. Bind

Function.prototype.myBind(context) {
    context = context || window;
    context.fn = this;
    let args = [...arguments].slice(1);
    
    return () => {
        return context.fn.apply(context, [...args]);
    }
}

11. call

Function.prototype.mycall = function(context) {
    if(typeof this !== function) {
        return;
    }
    
    context = context || window;
    let args = arguments.slice(1);
    context.fn = this;
    let result = context.fn(...args);
    delete context.fn;
    return result;
}

12. apply

Function.prototype.myapply = function(context) {
    if(typeof this !== function) {
        return;
    }
    let result;
    context = context || window;
    context.fn = this;
    if(arguments[1]) {
        result = context.fn(...argument[1])
    } else {
        result = context.fn();
    }
    delete context.fn;
    return result;
}

13. 下划线转驼峰

a.replace(/_(\w)/g, function(attr, letter) {
    letter.toUpperCase();
})

14. 驼峰转下划线

a.replace((/[A-Z]/g), '_$1').toLowerCase();