前端面试题刷题笔记(一)

1. 冒泡排序、插入排序、快速排序、堆排序?

冒泡:

function bubble(a){
    let temp
    for(let i=0,end=a.length-1;i<=end;i++){
          temp = a[i]
            for(let j=i;j<=end;j++){
                if(a[j]<temp){
                    [a[i],a[j]] = [a[j],a[i]]
                }
            }
        }
 }

插排: 

 function insertion(arr){
     let handle = [Infinity]
     for(let i=0,len=arr.length;i<len;i++){
          for(let j=0,hlen=handle.length;j<hlen;j++){
             if(arr[i]<=handle[j]||j===hlen-1){
                handle.splice(j,0,arr[i])
                break
             }
          }
     }
     handle.pop()
     return handle
}

快排:

function quickSort(arr,l,r){
    if(l>=r) return
    if(arguments.length===1){
        l=0
        r=arr.length-1
    }
    let i=l,j=r
    let a = arr[i]
    let right = true
    while(i<j){
        if(right){
            if(arr[j]<a){
                arr[i]=arr[j]
                arr[j]=a
                right=false
            }else{
                j--
            }
        }else{
            if(arr[i]>a){
                arr[j]=arr[i]
                arr[i]=a
                right=true
            }else{
                i++
            }
        }
    }
    quickSort(arr,l,i)
    quickSort(arr,i+1,r)
}

堆排:

function heapSort(arr,banLen=0){
    let length = arr.length
    if(length === banLen) return
    let grade = Math.floor(Math.log2(length-banLen))-1
    let maxPos=length-banLen-1
    let adjustHeap=(arr,index)=>{
        let len = Math.pow(2,index)
        let max,leftLeaf,rightLeaf
        for(let i=len-1;i<len;i++){
            leftLeaf = 2*i+1>maxPos?-Infinity:arr[2*i+1]
            rightLeaf = 2*i+2>maxPos?-Infinity:arr[2*i+2]
            max = Math.max(arr[i],leftLeaf,rightLeaf)
            if(arr[2*i+1]===max) [arr[i],arr[2*i+1]]=[arr[2*i+1],arr[i]]
            if(arr[2*i+2]===max) [arr[i],arr[2*i+2]]=[arr[2*i+2],arr[i]]
        }
    }
    for(let i=grade;i>=0;i--){
        adjustHeap(arr,i)
    }
    [arr[0],arr[maxPos]]=[arr[maxPos],arr[0]]
    heapSort(arr,++banLen)
}

2. 节流和防抖?

节流:

function throttle(fn,delay){
    let timer=null
    return function(...args){
        if(timer===null){
            fn.apply(this,args)
            timer = setTimeout(()=>{
                clearTimeout(timer)
                timer = null
            },delay)
        }
    }
}

防抖:

function debounce(fn,delay){
    let timer = null
    return function(...args){
        clearTimeout(timer)
        timer = setTimeout(()=>{
             fn.apply(this,args)
        },delay)
    }
}

3. 数组去重?

const unique = (arr)=>[...new Set(arr)] 

4.实现call、apply、bind、reduce?

call:

Function.prototype.myCall = function(self,...args){
    let s = Symbol()
    self = self||window
    self.__proto__[s] = this
    self[s](...args)
    delete self.__proto__[s]
}

apply:

Function.prototype.myApply = function(self,args){
   if(!(args instanceof Array)) throw('不是数组')
    let s = Symbol()
    self = self||window
    self.__proto__[s] = this
    self[s](...args)
    delete self.__proto__[s]
}

bind:

Function.prototype.myBind = function(self,...bindArgs){
    let fn = this
    return function(...args){
        fn.apply(self,[...bindArgs,...args])
    }
}

reduce:

Array.prototype.myReduce = function(fn,ori){
  let len = this.length
  let i = 0
  let a = ori===undefined?this[i++]:ori
  let b = this[i++]
  while(i<=len){
    a=fn(a,b)
    b=this[i++]
  }
  return a
}

 

5.如何判断变量A是不是一个Object?

instanceof是沿着原型链找,typeof是根据机器码的低位数来判断变量类型:

000:对象

1:整数

100:字符串

110:布尔

null:对应机器码的NULL指针,全是0

undefined: 用-(2^30)表示

由于null全是0,低位自然也都是0,因此typeof null === 'object'

判断一个变量是不是Object:

// A是一个Object
Object.prototype.toString.call(A)==='[object Object]'
// A是一个Array
Object.prototype.toString.call(A)==='[object Array]'
// A是Null
Object.prototype.toString.call(A)==='[object Null]'
// (A是null直接A===null判断即可,此处是为了说明null也能这么判断)

 6.柯里化?

function currying(fn){
    let allArgs = []
    function curryFun(...args){
        allArgs = [...allArgs,...args]
        if(!args.length) return fn.apply(this,allArgs)
        return curryFun
    }
    return curryFun
}
a={b:1,f(...args){console.log(this.b,args)}}
currying(a.f)(5)(6).apply(a)  //1 [5,6]

 

 7.深拷贝?

function getType(arg){
    return Object.prototype.toString.call(arg).replace(/\[object (.+)\]/,'$1')
}
function deepCopy(arg,map){
    let type = getType(arg)
    if(!(['Array', 'Object'].includes(type))) return arg
    let rtn = type === 'Array'?[]:{} 
    map = map || new WeakMap()
    map.set(arg,rtn)
    Object.keys(arg).map(item=>{
        if(map.has(arg[item])){
            rtn[item] = map.get(arg[item])
        }else{
            if(['Array', 'Object'].includes(getType(arg[item]))){
                map.set(arg[item],rtn)
            }
            rtn[item] = deepCopy(arg[item],map)
        }
    })
    return rtn
}

a={b:{c:[1,2,3]}}
a.b.c[0]=a
b=deepCopy(a)
console.log(b.b.c[0]===b) // true
console.log(b.b.c[0].b.c[0]===b) // true

 

posted @ 2019-08-28 15:11  goblin_pitcher  阅读(633)  评论(0编辑  收藏  举报