最近會把前陣子自己復盤歸類整理的這次跳槽面試遇到的所有題目發(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ī)定時間內函數(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秒內再次觸發(fā)會重新計算時間
timer = setTimeout(() => {
//確保this指向不會改變
func.apply(context, [...args]);
}, wait);
} else {
//第二種:立即執(zhí)行,n秒內不可再次觸發(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ù)一定時間內不會再次執(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('