引言 首先出这篇文章,一方面是为了记录巩固我所学的知识,明白面试的高频考点。不鼓励大家背题的,初衷是希望总结的一些面试题能帮助你查漏补缺,温故知新。这些题并不是全部,如果你还想看得更多,可以访问GitHub仓库 ,目前已经有552道大厂真题了,涵盖各类前端的真题,欢迎加入我们一起来讨论~
函数 call
语法:fn.call(obj,…args)
功能:执行fn,使this为obj,并将后面的n个参数传给fn
Function .prototype .myCall = function (obj, ...args ) { if (obj == undefined || obj == null ) { obj = globalThis } obj.fn = this let res = obj.fn (...args) delete obj.fn return res } value = 2 let foo = { value : 1 , } let bar = function (name, age ) { console .log (name, age, this .value ) } bar.myCall (foo, 'HearLing' , 18 ) bar.myCall (null , 'HearLing' , 18 )
apply
语法:fn.apply(obj,arr)
功能:执行fn,使this为obj,并arr数组中元素传给fn
Function .prototype .myAplly = function (obj, arr ) { if (obj == undefined || obj == null ) { obj = globalThis } obj.fn = this let res = obj.fn (...arr) delete obj.fn return res } value = 2 let foo = { value : 1 , } let bar = function (name, age ) { console .log (name, age, this .value ) } bar.myAplly (foo, ['HearLing' , 18 ]) bar.myAplly (null , ['HearLing' , 18 ])
bind
语法:fn.bind(obj,…args)
功能:返回一个新函数,给fn绑定this为obj,并制定参数为后面的n个参数
Function .prototype .myBind = function (obj, ...args ) { let that = this let fn = function ( ) { if (this instanceof fn) { return new that (...args) } else { return that.call (obj, ...args) } } return fn } value = 2 let foo = { value : 1 , } let bar = function (name, age ) { console .log (name, age, this .value ) } let fn = bar.myBind (foo, 'HearLing' , 18 )let a = new fn () console .log (a.__proto__ )
区别call()/apply()/bind() call(obj)/apply(obj): :调用函数, 指定函数中的this为第一个参数的值bind(obj): 返回一个新的函数, 新函数内部会调用原来的函数, 且this为bind()指定的第一参数的值
节流
理解:在函数多次频繁触发时,函数执行一次后,只有大于设定的执行周期后才会执行第二次
场景:页面滚动(scroll)、DOM 元素的拖拽(mousemove)、抢购点击(click)、播放事件算进度信息
功能:节流函数在设置的delay毫秒内最多执行一次(简单点说就是,我上个锁,不管你点了多少下,时间到了我才解锁)function throttle (fn, delay ) { let flag = true return (...args ) => { if (!flag) return flag = false setTimeout (() => { fn.apply (this , args) flag = true }, delay) } }
防抖
理解:在函数频繁触发是,在规定之间以内,只让最后一次生效
场景:搜索框实时联想(keyup/input)、按钮点击太快,多次请求(登录、发短信)、窗口调整(resize)
功能:防抖函数在被调用后,延迟delay毫秒后调用,没到delay时间,你又点了,清空计时器重新计时,直到真的等了delay这么多秒。function debounce (fn, delay ) { let timer = null return (...args ) => { clearTimeout (timer) timer = setTimeout (() => { fn.apply (this , args) }, delay) } }
节流与防抖的区别 首先概念上的不同,解释一下什么是防抖节流;然后就是使用场景的不同; 经典区分图:curry
function mycurry (fn, beforeRoundArg = [] ) { return function ( ) { let args = [...beforeRoundArg, ...arguments ] if (args.length < fn.length ) { return mycurry.call (this , fn, args) } else { return fn.apply (this , args) } } } function sum (a, b, c ) { return a + b + c } let sumFn = mycurry (sum)console .log (sumFn (1 )(2 )(3 ))
数组 数组去重 function unique (arr ) { const res = [] const obj = {} arr.foreach ((item ) => { if (obj[item] === undefined ) { obj[item] = true res.push (item) } }) return res }
数组扁平化 function flattern1 (arr ) { let res = [] arr.foreach ((item ) => { if (Array .isArray (item)) { res.push (...flattern1 (item)) } else { res.push (item) } }) return res }
对象 new function newInstance (Fn , ...args) { const obj = {} obj.__proto__ = Fn .prototype const result = Fn .call (obj, ...args) return result instanceof Object ? result : obj }
instanceof function instance_of (left, right ) { let prototype = right.prototype while (true ) { if (left === null ) { return false } else if (left.__proto__ === prototype) { return true } left = left.__proto__ } } let a = {}console .log (instance_of (a, Object ))
对象数组拷贝 浅拷贝 function cloneShallow (origin ) { let target = {} for (let key in origin) { if (origin.hasOwnProperty (key)) { target[key] = origin[key] } } return target } let obj = { name : 'lala' , skill : { js : 1 , css : 2 , }, } let newobj = cloneShallow (obj)newobj.name = 'zhl' newobj.skill .js = 99 console .log (obj)console .log (newobj)
深拷贝 function deepClone (source, hashMap = new WeakMap () ) { let target = new source.constructor ( ) if (source == undefined || typeof source !== 'object' ) return source if (source instanceof Date ) return source (Date ) if (source instanceof RegExp ) return source (RegExp ) hashMap.set (target, source) for (let key in source) { if (source.hasOwnProperty (key)) { target[key] = deepClone (source[key], hashMap) } } return target } let obj = { name : 'lala' , skill : { js : 1 , css : 2 , }, } let newobj = deepClone (obj)newobj.skill .js = 100 console .log (obj)console .log (newobj)
最后的话 🚀🚀 更多基础知识总结可以⭐️关注我,后续会持续更新面试题总结~
⭐️⭐️ 最后祝各位正在准备秋招补招和春招的小伙伴面试顺利,收割offer,我们一起加油吧🤝!还有就是快春节了,提前祝你新年快乐❤ ❤