前端面试必刷题附代码解析

128 阅读3分钟
  1. 排序相关,快排 归并 冒泡

冒泡

    // 冒泡排序
    function bubbleSort(arr) {
    //console.time('BubbleSort');
    // 获取数组长度,以确定循环次数。
    let len = arr.length;
    // 遍历数组len次,以确保数组被完全排序。
    for(let i=0; i<len; i++) {
        // 遍历数组的前len-i项,忽略后面的i项(已排序部分)。
        for(let j=0; j<len - 1 - i; j++) {
            // 将每一项与后一项进行对比,不符合要求的就换位。
            if(arr[j] > arr[j+1]) {
                [arr[j+1], arr[j]] = [arr[j], arr[j+1]];
            }
        }
    }
    //console.timeEnd('BubbleSort');
        return arr;
    }

选择排序

    // 选择排序
    function selectionSort(arr) {
    //console.time('SelectionSort');
    // 获取数组长度,确保每一项都被排序。
    let len = arr.length;
    // 遍历数组的每一项。
    for(let i=0; i<len; i++) {
        // 从数组的当前项开始,因为左边部分的数组项已经被排序。
        let min = i;
        for(let j=i; j<len; j++) {
            if(arr[j] < arr[min]) {
                min = j;
            }
        }
        if(min !== i) {
            [arr[min], arr[i]] = [arr[i], arr[min]];
        }
    }
    //console.timeEnd('SelectionSort');
    return arr;
    }

插入排序

    //console.time('InsertionSort');
    let len = arr.length;
    for(let i=1; i<len; i++) {
        let j = i;
        let tmp = arr[i];
        while(j > 0 && arr[j-1] > tmp) {
            arr[j] = arr[j-1];
            j--;
        }
        arr[j] = tmp;
    }
    //console.timeEnd('InsertionSort');
    return arr;
}

快排

    function quicksort(arr) {
        let n = arr.length;
        let mid = Math.floor(n / 2);
        var pivot = arr.splice(mid, 1)[0];
        let left = [], right = [];
        for(let i = 0; i < n; i++) {
            if(arr[i] < pivot) {
                left.push(arr[i))
            } else {
                right.push(arr[i])
            }
       }
       return quicksort(left).concat([pivot, quicksort(right)])
    }
  1. 二分查找

  2. 实现new

    function new(fn, ...args) {
        let obj = Object.create(fn.protoType);
        let res = obj.apply(this, args)
        return typeof obj === 'function' || typeof obj === 'object' : obj : res;
   }
  1. 实现instanceOf

    function instanceOf(left, right) {
        let proto = Object.getPrototypeOf(left);
        let right = right.protoType;
        while(true) {
            if(left === null) return false;
            if(left === right) return true;
            left = Object.getPrototypeOf(left);
        }
    }
  1. 实现节流

    function throttle (fn, delay) {
        let timer = null;
        return function(...args) {
            if(timer) {
                return
            } else {
                timer = setTimeout(() => {
                    fn.apply(fn, args);
                    timer = null
                }, delay)
            }
        }
    }
  1. 实现防抖

    function debounce(fn, delay) {
        let timer = null;
        return function(...args) {
            if(timer) {
                clearTimeout(timer);
            } else {
                timer = setTimeout(() => {
                    fn.apply(fn, args);
                }, delay)
            }
        }
    }
  1. 实现promise.all

    function promiseAll(promises) {
        let sum = 0,arr= [];
        promises.forEach((item, index) => {
            item.resolve().then(data => {
                arr[index] = data;
                sum++;
                if(sum === promises.length) {
                    Promise.resolve(arr);
                }
            }).catch(err => {
                reject(err)
            })
        })
    }
  1. 实现promise.race(then只拿到最快的结果)
    function promiseRace(promises) {
        promises.forEach((item, index) => {
            item.resolve().then(data => {
                Promise.resolve(data);
            }).catch(err => {
                reject(err)
            })
        })
    }
  1. 实现promise

    class myPromise {
        constructor(fn) {
            this.callback = [];
            const resolve = function(value) {
                this.data = value;
                while(this.callback.length) {
                    let cb = this.callback.unshift();
                    cb(this.data);
                }
            }
            fn(reslove)
        }
        then(onCallback) {
            return new myPromise(reslove => {
                this.callback.push(() => {
                    const res = onCallback(this.data);
                    if(res instanceOf myPromise) {
                        res.then(resolve)
                    } else {
                        resolve(res)
                    }
                })
            })
        }
    }
  1. 实现数组去重
    funtion unique(arr) {
        return Array.from(new Set(arr));
    }
    
    function unique(arr) {
        let tmp = {}, map = new Map();
        let res = [];
        arr.forEach(item => {
            if(!map.has(item)) {
                map.set(item, 1);
                res.push(item);
            }
        })
        return res
    }
    
    function unset(arr) {
        let res = [];
        arr.forEach((item, index) => {
            if(item.indexOf(arr) === idex) {
                res.push(item);
            }
        })
        return res
    }
  1. 实现数组扁平化
    function flat(arr) {
        let res =[];
        arr.forEach(item => {
           res.concat(Array.isArray(item) ? flat(item) : item);
        })
        return res
    }
   
    function flat(arr) {
        return JSON.parse('[' +JSON.Stringify(arr).replace(/\[|\]/g) + ']')
    }
  1. 实现函数柯里化
    function currying(fn) {
        let params = [];
        return function curry(...args) {
            if(args.length) {
                params = [...params, ...args]
                return curry
            } else {
                let res = fn.apply(this, params);
                params = [];
                return res
            }
        }
    }
  1. 实现eventEmitter
    class eventEmitter {
        constructor() {
            this.events = {}
        }
        on(event, callback) {
            this.events[event].push(callback);
        }
        off(event, callback) {
            this.events[event].filter(item => item !== callback
            )
        }
        emit(event, ...args) {
            this.events[event].forEach(cb => {
                cb(args);
            })
        }
    }
  1. 实现树的层次遍历
    function levelOrder(tree) {
        const res = [];
        function _levelOrder(node, level) { 
        if (!node) return null; // 当前层数组初始化 
            res[level] = res[level] || [];
            res[level].push(node.val); // 下一层 +1 
            _levelOrder(node.left, level + 1);
            _levelOrder(node.right, level + 1);
        } 
        _levelOrder(root, 0); 
        return res;
    }
  1. 实现树的前序、后续遍历
    function dfs(tree) {
        if(!tree) return;
        let res =[];
        if(tree.val) {
            res.push(tree)
        }
        dfs(tree.left);
        dfs(tree.right);
        return res;
    }
  1. 实现组合继承
    function parents(name) {
        this.name = name;
    }
    parents.protoType.sayHi = ()=> console.log(this.name)
    function child(name) {
        parents.call(this,name);
    }
    child.protoType = new parents();
    child.protoType.constructor = child;
  1. 实现bind
    Function.prototype.myBind = function(ctx, ...args) {
         const that = this;
         const fn = function(){}
         const bind = function(){
             const _this = this instanceof fn ? this : ctx
             return self.apply(_this, [...args, ...arguments])
         }
         delete fn
         return bind
    }
  1. 实现call
    Function.prototype.myCall = function(ctx, ...args) {
        ctx = ctx || window;
        let fn = Symbol();
        ctx[fn] = this;
        let res = ctx[fn](args);
        delete ctx[fn];
        return res;
    }
    
    let obj = { name: 沐华 }
    function foo(){ return this.name } // 就是把 foo 函数里的 this 指向,指向 obj 
    console.log( foo.myCall(obj) ) // 沐华
  1. 实现深拷贝
    function deepClone(target, map = new Map()) {
        let result; 
        if (typeof target === 'object') {
            if (Array.isArray(target)) { 
                result = [] 
                for (let i in target) {
                    result.push(deepClone(target[i]))
                } 
            } else { 
                result = {} 
                for (let key in target) {
                    result[key] = target[key]
                }
            } 
        } else {
            result = target;
        }
        return result;
    }
  1. 实现ajax
    function ajax(url, params) {
        const xml = new XMLHttpRequest();
        xml.open('get',url, params);
        xml.send();
        xml.onreadystatechange(res => {
            if(res.status === 200 && res.readyStatus === 4) {
                 Promise.resolve(res.responseText);
            } else {
                throw new Error('ajax error')
            }
        })
    }
  1. 手写Promise
    function Promise(fn) {
        this.cbs = [];
        const resolve = (value) => {
            setTimeout(() => {
                this.data = value;
                this.cbs.forEach(cb => cb());
            })
        }
        fn(resolve);
    }
    
    Promise.protoType.then = funtion(onResolve) {
        return new Promise((resolve) => {
            this.cbs.push(() => {
                const res = onResolve(this.data);
                if(res instance Promise) {
                    res.then(resolve);
                } else {
                    resolve(res);
                }
            })
        })
    }
    
    new Promise(reslove => {
        setTimeout(() => {
            resolve(1)
        }, 100)
    }).then(res => {
        console.log(res)
        new Promise(reslove => {
        setTimeout(() => {
            resolve(2)
        }, 100)
    }).then(res => {
        console.log(res)
    })

22 手动控制并发请求

    function multiFunctions(urls, maxNum) {
        const len = urls.length;
        let count = 0;
        const result = new Array(len).fill(false);
        new Promise((resolve, reject) => {
            while(count < maxNum) {
                next()
            }
            function next() {
                let current = count++;
                // 给出终止条件
                if(current >= len) {
                    !result.includes(false) && reslove(result)
                }
                let url = urls[current];
                fetch(url).then(res => {
                    result[current] = res;
                    if(current < len) {
                        next()
                    }
                }).catch(err => {
                    res[current] = err;
                    if(current < len) {
                        next()
                    }
                }
            }
        })
    }

23 实现一个发布订阅模式

    class Sub{
        constructor(){
            this.subs = [];
            this.state = 0;
        }
        
        addSub(sub){
            if(!subs.includes(sub)) {
                subs.push(sub)
            } else {
                console.log('sub has Exist')
            }
        }
        
        removeSub(sub) {
            let index = subs.indexOf(sub);
            if(index === -1) {
                console.log('sub do not exist')
            } else {
                this.subs.splice(index, 1);
            }
        }
        
        notify(){
            this.subs.forEach(item => {
                sub.update(this.state);
            })
        }
        
        doSomeLogic(state) {
            this.state = state;
            this.notify()
        }
    }

    class obeserve{
        constructor(name) {
            this.name = name
        }
        
        update(state) {
            console.log(this.name + 'update' + state)
        }
    }
    
    var observerA = new Observer("A");
    var observerB = new Observer("B");
    var subject = new Subjects();
    subject.addSubs(observerA);
    subject.addSubs(observerB);
    subject.doSomeLogic();
    subject.doSomeLogic();
    subject.removeSubs(observerB);
    subject.doSomeLogic();

24 解析url为对象

    

25 下一个排列

 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var nextPermutation = function(nums) {
   const n = nums.length -1;
   let i = n -1, j =n;
   while(i >=0 && nums[i] >= nums[i+1]) i--;
   if(i >=0) {
        while(j>=0 && nums[j] <= nums[i]) j--;
        [nums[i],nums[j]] = [nums[j], nums[i]];
   }
   let l = i + 1,
		r = n;
   while(l<r){
        [nums[l], nums[r]] = [nums[r], nums[l]];
        l++;
        r--;
   }
};