每日一题,巩固基础
自己做一遍,写上自己的解法和做题时遗忘的知识点
这样不仅能巩固知识,写上自己的想法也方便以后查阅和复习
题目来源: https://github.com/Advanced-Frontend/Daily-Interview-Question
第1题-2019/3/24
- 题目
['1', '2', '3'].map(parseInt)
答案: [1,NaN,NaN]
- 复习
parseInt(string, radix) // string表示被解析的字符串,radix按照什么进制来解析
- 分析
['1','2','3'].map(parseInt)
// 等价于下面
['1','2','3'].map((val,index) => parseInt(val,index))
* 步骤
// parseInt(‘1’,0),按照10进制解析,返回1
// parseInt(‘2’,1),按照1进制解析,但是被解析字符串为2大于1进制的最大数1所以返回NaN
// parseInt(‘3’,2), 同上返回NaN
第2题-2019/3/25
防抖函数与节流函数的区别?
防抖函数
比如一个请求按钮,你快速点击多次,如果没有防抖函数就会发出多次请求,浪费带宽和性能,有了防抖函数,快速点击多次我也只发送最后一次的点击请求
简单版防抖函数
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi)); // 防抖
- Es6写法,绑定this
const debounce = (fn,wait) => {
let timer = null //存放定时器的返回值
return function(...args){
// 如果await期间点击多次,清除前面触发的,只执行最后一次
if(timer) clearTimeout(timer)
timer = setTimeout(() => { //注意这里Es6写法和Es5写法有区别
// 绑定this,确保上下文执行环境
fn.apply(this,args)
},wait)
}
}
function sayHi() {
console.log(this) //<input type="text" id="inp">
}
- Es5写法,绑定this
const debounce = (fn,wait) => {
let timer = null
return function(...args){
if(timer) clearTimeout(timer)
timer = setTimeout(function(){ //Es5写法
fn.apply(this,args)
},wait)
}
}
function sayHi() {
console.log(this) // window
// 因为Es6写法有块级作用域,函数的this在生成时就已经确定了
// Es5没有块级作用域,this在函数执行的时候,由其上下文执行环境确定
}
- Es6写法不绑定this
const debounce = (fn,wait) => {
let timer = null
return function(...args){
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
// 不绑定this,确保上下文执行环境
fn.apply()
},wait)
}
}
function sayHi() {
console.log(this) //window
}
延迟函数高级版
根据传入的参数决定是否立即执行,还是延迟执行
立即执行: 输入一个字符就发送一次请求
延迟执行: 输入下一个字符时间小于设定的wait时间,那么就清理上一次触发的事件,执行当前触发的事件
function debounce(fn,wait,immediate){
let context, context, timer
//延迟执行函数
const later = () => setTimeout(() => {
// 延迟函数执行完毕,清空缓存的定时器序号
timer = null
if(!immediate){
fn.apply(context,args)
// 闭包函数使用后的变量不会被清理,手动清理防止内存泄漏
context = args = null
}
})
return function(...params){
if(!timer){
// 如果没有创建延迟执行函数(later),就创建一个
timer = later()
if(immediate){
// 立即执行,不用setTimeout
fn.apply(this,params)
}else{
context = this
args = params
}
}else{
clearTimeout(timer)
//取消上一个,执行下一个
timer = later()
}
}
}
节流函数
防抖动是将多次执行变成执行最后一次,节流是将多次执行,变成每隔一段时间执行
function throttle(fn,wait){
let flag = true // 通过闭包保存一个标记
return function(){
if(!flag) return
// 设置falg为false,本次事件没执行完,如果又发生调用,上面flag就会return
// 所以不会再触发一个事件
flag = false
setTimeout(() => {
fn.apply(this,arguments)
// 设置flag为turn表示本次事件执行完了,可以执行下一次的
flag = true
})
}
}
导致节流和防抖函数的细微区别是因为闭包,这里顺便复习下闭包
function fa() {
var a = 1;
return function () {
console.log(a)
a++
}
}
var o = fa();
o(); // 1
o(); // 2
参考文章: https://www.cnblogs.com/blowfish/p/3323357.html
https://www.cnblogs.com/yakun/p/3932026.html