面试中常用的算法以及手写程序题

函数防抖

function debounce (fn,wait){
    var timmer = null;
    return function (){
        clearTimeout(timmer);
        timmer = setTimeout(()=>{
            fn.apply(this,arguments);
        },wait)
    }
}

函数节流

function throttle (fn,wait){
    let canRun = true;
    return function (){
        if(!canRun){
            return;
        }
        canRun = false;
        setTimeout(()=>{
            fn.apply(this,arguments);
            canRun = true;
        },wait)
    }
}

new操作符

function myNew (fn){
    var newObj = {};
    newObj.__proto__ = fn.prototype;
    newObj.apply(fn,arguments);
    return newObj;
}

自定义new

function create() {
    // 创建一个空的对象
    let obj = new Object()
    // 获得构造函数
    let Con = [].shift.call(arguments)
    // 链接到原型
    obj.__proto__ = Con.prototype
    // 绑定 this,执行构造函数
    let result = Con.apply(obj, arguments)
    // 确保 new 出来的是个对象
    return typeof result === 'object' ? result : obj
}

数组扁平化flat

function flat(arr){
    return arr.toString().split(',').map((item)=>{
        return Number(item);
    })
}

function flat(arr){
    return arr.reduce((a,b) => {
        return a.concat(Array.isArray(b) ? flat(b) : b)
    },[])
}

function flat(arr){
    var res = [];
    arr.map((item)=>{
        if(Array.isArray(item)){
            res = res.concat(flat(item))
        } else {
            res.push(item)
        }
    })
    return res;
}

- es6
Array.prototype.flat(arr);

函数柯里化

function curry(arr){
    var args = [].slice.call(arguments,1)
    return ()=>{
        var newArgs = args.concat([].slice.call(arguments))
        return arr.apply(this,newArgs)
    }
}

var currying = function(fn){
    var args = [];
        return function inner(){
            if(arguments.length === 0){
                return fn.apply(this, args);
            }else{
                [].push.apply(args, arguments);
                return inner;
            }
        }
};

function curry(fn,args){
    var length=fn.length;  //fn函数的形参个数
    var args=args || [];   //第一次接收的参数
    return function(){
        var newArgs=args.concat(Array.prototype.slice.call(arguments));//第二次接收的参数
        if(newArgs.length<length){
            return curry.call(this,fn,newArgs);  //参数没有达到形参个数时,递归调用
        }else{
            return fn.apply(this,newArgs);
        }
    }
}

数组去重

- es6
Array.from(new Set(arr));

var result = arr.filter((item,index) => {
    return arr.indexOf(item) === index
})

let newArr = []
let result = arr.forEach(item => {
    if(newArr.indexOf(item) === -1) {
        newArr.push(item)
    }
})

数组排序

冒泡排序

function cancelBubble(arr){
    for (var i=0;i<arr.length-1;i++){
        for (var j=0;j<arr.length-1-i;j++){
            if(arr[j]>arr[j+1]){
                var temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp
            }
        }
    }
    return arr;
}

选择排序

let min; // 最小值
let pos; // 最小值下标
function selectSort(arr){
    for(var i=0;i<arr.length;i++){
        min = arr[i];
        pos =i;
        for(var j=i+1;j<arr.length;j++){
            if(arr[j]<min){
                min = arr[j];
                pos =j;
            }
        }
        var temp = arr[i];
        arr[i] = min;
        arr[pos] = temp
    }
}

插入排序

function insertSort(arr){
    for(var i =0;i<arr.length;i++){
        for(var j=i;j>0 && arr[j] < arr[j-1];j++){
            var temp = arr[j]
            arr[j] = arr[j-1]
            arr[j-1] = temp
        }
    }
}

快速排序

var newArr=[];
function quickSort(arr){
    var pivot= arr[0],left=[],right=[];
    for(var i=0;i<arr.length;i++){
        if(arr[i]>pivot){
            left.push(arr[i])
        } else {
            right.push(arr[i])
        }
    }
    return newArr.concat(quickSort(left),pivot,quickSort(right))
    // return [...quickSort(left), pivot, ...quickSort(right)];
}

函数bind实现

Function.prototype.bind = function (context) {
    var self =this;
    return function () {
        self.apply(context)
    }
}
Function.prototype.bind = function (context){
    var self =this;
    //获取bind函数从第二个参数到最后一个参数
    var args = Array.prototype.slice.call(arguments,1);
    return function (){
        var bindArgs = Array.prototype.slice.call(arguments);
        self.apply(context, args.concat(bindArgs));
    }
}

数组

map实现

map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理的后值。
Array.prototype.map = function(fn) {
    let newArr = [];
    for (let i = 0; i < this.length; i++) {
        newArr.push(fn(this[i]))
    };
    return newArr;
}

filter实现

Array.prototype.filter = function(fn){ 
    let newArr = []; 
    for(let i = 0; i <this.length; i++){ 
        fn(this[i])&& newArr.push(this[i]); 
    } 
    return newArr; 
}

reduce实现

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
Array.prototype.reduce = function (reducer,initVal) {
    for(let i=0;i<this.length;i++){
        initVal =reducer(initVal,this[i],i,this);
    }
    return initVal
};

find实现

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
Array.prototype.find = function(fn) {
    for (let i = 0; i < this.length; i++) {
        if (fn(this[i])) return this[i]
    }
}

some实现

some() 方法会依次执行数组的每个元素:如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。如果没有满足条件的元素,则返回false。
Array.prototype.some=function (fn) {
    for(let i=0;i<this.length;i++){
        if(fn(this[i])) {
            return true
        }
    }
    return false
};

every实现

every方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
Array.prototype.every=function (fn) {
    for(let i=0;i<this.length;i++){
        if(!fn(this[i])) {
            return false
        }
    }
    return true
};

promise封装ajax

function getJSON (url) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open('GET', url, true)
        // xhr.open("POST", url, true)
        // xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(this.responseText, this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }
        xhr.send()
    })
}
留下你的脚步
推荐阅读