1.手写一个深拷贝
// 深克隆
function deepClone(sourceData){
// 判断数据类型
let dataType = Object.prototype.toString.call(sourceData).slice(8,-1);
if(dataType === 'Object'){
// 1.当前数据类型为对象
let subData = {};
// 遍历当前对象属性并递归克隆
for(let key in sourceData){
subData[key] =deepClone(sourceData[key])
}
return subData;
}else if(dataType === 'Array'){
//2.当前数据类型为数组
let subArr = [];
//遍历当前数组递归
for(let i=0;i<sourceData.length;i++){
subArr[i] = deepClone(sourceData[i]);
}
return subArr;
}else if(dataType === 'Data'){
//3.当前数据类型为日期
return new Data(sourceData.valueOf())
}else if(dataType === 'RegExp'){
//4.当前数据类型为正则对象
return new RegExp(sourceData);
}else if(dataType === 'Function'){
//5. 当前数据类型为函数
return new Function('return '+sourceData.toString()).call(this)
}else if(dataType ==='Map'){
//6.当前数据类型为Map
let subMap = new Map();
sourceData.forEach((value,key)=>{
subMap.set(key,deepClone(value))
})
return subMap;
}else if(dataType === 'Set'){
//7.当前数据类型为Set
let subSet = new Set();
for (let val of sourceData.values()){
subSet.add(deepClone(val));
}
return subSet;
}
// 8.其他数据类型直接返回
return sourceData;
}
备注:Object.prototype.toString.call()方法
2.手写防抖与节流
2.1 防抖
// 防抖
function debounce(fn,delay){
let timer
return function(){
if(timer){
clearTimeOut(timer)
}else{
timer = setTimeout(fn,delay)
}
}
}
2.2 节流
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
备注:
节流函数并不止上面这种实现方案,
例如可以完全不借助setTimeout,可以把状态位换成时间戳,然后利用时间戳差值是否大于指定间隔时间来做判定。
也可以直接将setTimeout的返回的标记当做判断条件-判断当前定时器是否存在,如果存在表示还在冷却,并且在执行fn之后消除定时器表示激活,原理都一样
3.手写一个Promise
4.手写一个axios
5. 排序与去重
6.闭包