App下載

2020年面試會遇到的手寫 Pollyfill 都在這里了

猿友 2020-10-10 12:00:32 瀏覽數(shù) (3372)
反饋

最近會把前陣子自己復(fù)盤歸類整理的這次跳槽面試遇到的所有題目發(fā)布到公眾號,這是第一篇。不要驚訝,上次跳槽考的也基本是這些題目,時間長了會忘,你只是需要一個清單!

new

測試用例:

function Fn (name) {
  this.name = name
}
console.log(myNew(Fn('lulu')))

實現(xiàn):

function myNew () {
  const obj = {}
  const Fn = Array.prototype.shift.call(arguments)
  // eslint-disable-next-line no-proto
  obj.__proto__ = Fn.prototype
  const returnVal = Fn.apply(obj, arguments)
  return typeof returnVal === 'object' ? returnVal : obj
}

bind

測試用例:

this.x = 9
const obj = {
  x: 81,
  getX: function () {
    return this.x
  }
}
console.log(obj.getX()) // 81


const retrieveX = obj.getX
console.log(retrieveX()) // 9


const boundGetX = retrieveX.bind(obj)
console.log(boundGetX()) // 81

實現(xiàn):

Function.prototype.mybind = function () {
  const outerArgs = Array.from(arguments)
  const ctx = outerArgs.shift()
  const self = this
  return function () {
    const innerArgs = Array.from(arguments)
    return self.apply(ctx, [...outerArgs, ...innerArgs])
  }
}

instanceof

測試用例:

console.log(myInstanceof("111", String)); //false
console.log(myInstanceof(new String("111"), String));//true

實現(xiàn):

function myInstanceof(left, right) {
    //基本數(shù)據(jù)類型直接返回false
    if(typeof left !== 'object' || left === null) return false;
    //getProtypeOf是Object對象自帶的一個方法,能夠拿到參數(shù)的原型對象
    let proto = Object.getPrototypeOf(left);
    while(true) {
        //查找到盡頭,還沒找到
        if(proto == null) return false;
        //找到相同的原型對象
        if(proto == right.prototype) return true;
        proto = Object.getPrototypeOf(proto);
    }
}

debounce

在規(guī)定時間內(nèi)函數(shù)只會觸發(fā)一次,如果再次觸發(fā),會重新計算時間。

/*** 
 * @description 防抖函數(shù)
 * @param func 函數(shù)
 * @param wait 延遲執(zhí)行毫秒數(shù)
 * @param immediate 是否立即執(zhí)行
 * */
function debouncing(func, wait = 1000, immediate = true) {
    let timer = null;
    return function () {
        let args = arguments;
        let context = this;
        if (timer) {
            clearTimeout(timer);
        }
        if (!immediate) {
            //第一種:n秒之后執(zhí)行,n秒內(nèi)再次觸發(fā)會重新計算時間
            timer = setTimeout(() => {
                //確保this指向不會改變
                func.apply(context, [...args]);
            }, wait);
        } else {
            //第二種:立即執(zhí)行,n秒內(nèi)不可再次觸發(fā)
            let callnew = !timer;
            timer = setTimeout(() => {
                timer = null;
                console.log('kaka')
            }, wait);
            if (callnew) func.apply(context, [...args])
        }
    }
}


function fn() {
    console.log('debluncing')
}


let f1 = debouncing(fn, 1000);


setInterval(() => {
    f1()
}, 1000);

throttle

節(jié)流指的是函數(shù)一定時間內(nèi)不會再次執(zhí)行,用作稀釋函數(shù)的執(zhí)行頻率。

/**
 * @description 節(jié)流函數(shù)
 * @param func 函數(shù)
 * @param wait 延遲執(zhí)行毫秒數(shù)
 * @param type 1:時間戳版本 2: 定時器版本
 *  */
function throttle(func, wait = 1000, type = 1) {
    if (type === 1) {
        let timeout = null;
        return function () {
            const context = this;
            const args = arguments;
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    func.apply(context, [...args]);
                }, wait);
            }
        }
    } else {
        let previous = 0;
        return function () {
            const context = this;
            const args = arguments;
            let newDate = new Date().getTime();
            if (newDate - previous > wait) {
                func.apply(context, [...args]);
                previous = newDate;
            }
        }
    }


}


function fn() {
    console.log('throttle')
}


const f1 = throttle(fn);


setInterval(() => {
    f1()
}, 100);

deepClone

測試用例:


const map = new Map()
map.set('key', 'value')
map.set('name', 'kaka')


const set = new Set()
set.add('11').add('12')


const target = {
  field1: 1,
  field2: undefined,
  field3: {
    child: 'child'
  },
  field4: [
    2, 8
  ],
  empty: null,
  map,
  set
}
target.target = target
const target1 = deepClone(target)
target1.a = 'a'
console.log('

0 人點贊