「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
前言
大家好,我是cv竹叶,面试的时候经常遇到要求手写解题,为了防止题留空白,今天我们就来学习几道高频的手写题目吧!万一中了呢!
手写相关
手写new函数
思路:以Object对象创建新对象,再把传入的函数this转向新对象的this,然后再对结果类型进行判断是函数还是对象,再返回。
function myNew(fn,...item){
let obj = Object.create(fn.prototype);//以旧的构造函数创建obj对象;
let res = fn.call(obj,...item);//把旧的this指向新的obj对象
if(res&&(typeof res === 'object' || typeof res === 'function')){
return res;//返回新的对象
}
return obj;
}
function Person(name, age) {
this.name = name;
this.age = age;
}
let obj = myNew(Person, "竹叶", 666);
obj.name;//竹叶
手写bind函数
思路:借用call()、apply()函数改变this指向,运用arguments获取全部传入的参数值进行重新赋值,最终返回一个新的对象。
Function.prototype.myBind = function(thisArg){
if(typeof this !== 'function') {
throw TypeError("必须是函数")
}
const args = Array.prototype.slice.call(arguments,1),//取出除了第一个this,其他的数组值,构造函数
self = this,
newfn = function(){},//用于保存原函数的原型
bound = function(){
return self.apply(
this instanceof newfn ? this : thisArg,
args.concat(Array.prototype.slice.call(arguments))//获取传入bound函数的值
)
}
//有传入对象,重新指定this到保存函数
if(this.prototype){
newfn.prototype = this.prototype;
}
bound.prototype = new newfn();//修改绑定函数的原型指向
return bound;
}
let obj = {
name:'竹叶',
}
function test(x,y,z){
console.log(this.name,x+y+z)
}
let Bound = test.myBind(obj,1,2)
Bound(3);//竹叶 6
new Bound(2);//undefined 5
手写实现防抖
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间(每次触发前都取消之前的延时调用方法)
用到场景:搜索输入框
思路:给定指定时间,在时间内如果再次触发,则重新执行执行函数。
function clickFn(fn,delay){
let timer = null;
return function(){
let that = this;
let args = [...arguments]//点击事件的事件组,构造函数
if(timer) clearTimeout(timer);//清掉之前的时间,重新计算时间
timer = setTimeout(function(){
fn.call(that,...args);//为了防止 this 指向改变,确保上下文为当前的this,传递参数
},delay)
}
}
function testFn(){
console.log('竹叶')
}
document.addEventListener('click',clickFn(testFn,1000))
手写实现节流
节流:高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率 思路:每次触发事件时都判断当前是否有等待执行的延时函数,需要一个标记
使用场景:滚动加载更多
思路:在给定的时间内,只能执行一次函数,执行完成后再重新按时间执行一次。
function clickFn(fn,delay){
let timer = null;
let isNext = false;
return function(){
if(isNext) return;//时间到了才执行下一步,否则返回
let args = [...arguments];//点击事件的事件组,构造函数
let that = this;
isNext = true;
if(timer) clearTimeout(timer);
timer = setTimeout(function (){
fn.call(that,...args);//为了防止 this 指向改变,确保上下文为当前的this,传递参数
isNext = false;
},delay)
}
}
function testFn(){
console.log('竹叶')
}
document.addEventListener('input',clickFn(testFn,1000))//监听输入频繁
结言
会写了吗?就算不会写,思路也要有哦,至少能在面试官面前加点分。如果对你有帮助就点个赞吧!