最近會(huì)把前陣子自己復(fù)盤歸類整理的這次跳槽面試遇到的所有題目發(fā)布到公眾號(hào),這是第一篇。不要驚訝,上次跳槽考的也基本是這些題目,時(shí)間長了會(huì)忘,你只是需要一個(gè)清單!
new
測試用例:
function Fn (name) {
this.name = name
}
console.log(myNew(Fn('lulu')))
實(shí)現(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
實(shí)現(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
實(shí)現(xiàn):
function myInstanceof(left, right) {
//基本數(shù)據(jù)類型直接返回false
if(typeof left !== 'object' || left === null) return false;
//getProtypeOf是Object對(duì)象自帶的一個(gè)方法,能夠拿到參數(shù)的原型對(duì)象
let proto = Object.getPrototypeOf(left);
while(true) {
//查找到盡頭,還沒找到
if(proto == null) return false;
//找到相同的原型對(duì)象
if(proto == right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
debounce
在規(guī)定時(shí)間內(nèi)函數(shù)只會(huì)觸發(fā)一次,如果再次觸發(fā),會(huì)重新計(jì)算時(shí)間。
/***
* @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ā)會(huì)重新計(jì)算時(shí)間
timer = setTimeout(() => {
//確保this指向不會(huì)改變
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ù)一定時(shí)間內(nèi)不會(huì)再次執(zhí)行,用作稀釋函數(shù)的執(zhí)行頻率。
/**
* @description 節(jié)流函數(shù)
* @param func 函數(shù)
* @param wait 延遲執(zhí)行毫秒數(shù)
* @param type 1:時(shí)間戳版本 2: 定時(shí)器版本
* */
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('