1. 防抖和节流
防抖 ⭐
function debounce(fn,wait){
var timer = null;
return function(){
let _this = this
let agrs = [...arguments]
if(timer !== null){
clearTimeout(timer);
}
timer = setTimeout(function(){
fn.apply(_this,args)
},wait);
}
}
节流 ⭐⭐⭐
-
第一次就执行
function trol(fn,delay){ var last = 0 return function(){ var now = Date.now() if(now - last > delay){ fn.apply(this,arguments) last = now } } } -
第一次不立即执行,延时delay
function trol(fn,delay){ let timer = null return function(){ let context = this let args = arguments if(timer === null){ timer = setTimeout(()=>{ fn.apply(context,args) timer = null },delay) } } } -
最后执行
function trol(fn,delay){ let startTime= Date.now() let timer = null return function(){ let context = this let args = arguments let currTime = Date.now() let remaining = delay - (currTime - startTime) clearTimeout(timer) if(remaining <= 0){ fn.apply(context,args) startTime = Date.now() }else{ timer = setTimeout(fn,remaining) } } }
2. 深拷贝 ⭐⭐
-
自定义方法
function deepClone(obj){ let newTarget = Array.isArray(obj) ? [] : {} if(obj && typeof obj === 'object'){ for(let key in obj){ if(typeof obj[key] === 'object'){ newTarget[key] = deepClone(obj[key]) }else{ newTarget[key] = obj[key] } } } return newTarget } -
JSON
let obj = { a: 1, b: [2,3,5], c: function(){} } let res = JSON.parse(JSON.stringify(obj)) console.log(res); //c会被忽略
3. 数组扁平化 ⭐⭐
-
自带方法
let arr = [1,2,[3,4,[5,6]]] arr.flat(Infinity) -
递归
function flat(arr){ return arr.reduce((pre,cur)=>{ return pre.concat(Array.isArray(cur) ? flat(cur) : cur) },[]) } -
队列
function flat(arr){ let res = [] while(arr[0] !== undefined){ let temp = arr.shift() if(Array.isArray(temp)){ arr.unshift(...temp) }else{ res.push(temp) } } return res } -
字符串处理
function flat(arr){ return arr.toString().split(',').map(v=>Number(v)) }
4. 单例模式 ⭐⭐
-
绑定在构造函数的静态方法上
-
使用闭包
//构造函数 function SingleTon(){ } //工具函数 var getInstance = (function(){ var instance return function(){ if(!instance){ instance = new SingleTon() } return instance } })();
5. 数组去重 ⭐⭐⭐
-
Set集合
let res = [...new Set(arr)] //let res = Array.from(new Set(arr)) console.log(res); -
Map
function fn(arr){ let res = [], map = new Map() for(let i=0;i<arr.length;i++){ let temp = arr[i] if(map.has(arr[i])){ map.set(temp,true) }else{ res.push(temp) map.set(temp,false) } } return res } -
indexOf
function fn(arr){ let res = [] arr.forEach(v=>{ if(res.indexOf(v) === -1){ res.push(v) } }) return res }
6. 手写Promise的all和race ⭐⭐
- 手写PromiseAll()
function myPromiseAll(promiseArr){
return new Promise((resolve,reject)=>{
let count = 0,
res = []
for(let i=0;i<promiseArr.length;i++){
Promise.resolve(promiseArr[i]).then(data=>{
res[i] = data
count ++
if(count === promiseArr.length){
resolve(res)
}
}).catch(err=>{
reject(err)
})
}
})
}
- 手写 Promise.race
function myPromiseRace(promiseArr){
return new Promise((resolve,reject)=>{
promiseArr.forEach(v=>{
Promise.resolve(v).then(data=>{
resolve(data)
}).catch(err=>{
reject(err)
})
})
})
}
7. 模式实现 New ⭐
- 新建一个空对象
obj - 把这个空对象的原型执行构造函数的原型
- 改变this的指向执行构造函数
- 如果构造函数的结果返回的是一个对象则返回该对象,否则返回
obj
function _new(Fn,...args){
let obj = {}
obj.__proto__ = Fn.prototype
let res = Fn.apply(obj,args)
return res instanceof Object ? res : obj
}
8. 实现call/apply/bind ⭐⭐⭐
-
实现call
Function.prototype.myCall = function(context,...args){ let _this = this // XXXX.myCall => XXX context = context ? Object(context) : Window context.fn = _this let r = context.fn(...args) delete context.fn return r } -
实现 apply
Function.prototype.myApply = function(context,args){ let _this = this context = context ? Object(context) : Window context.fn = _this if(!args){ context.fn() }else{ context.fn(args) } delete context.fn } -
实现 bind
- js bind的多次绑定只有第一次是有效的
- 在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。
FUnction.prototype.myBind = function(context){ let args = [...arguments].slice(1) let _this = this fBound = function(){ return _this.apply(this instanceof fBound ? this : context,args.concat([...arguments])) } fBound.prototype = this.prototype return fBound }
9. 模式Object.create()实现 ⭐
Object.create()会将参数对象作为一个新创建的空对象的原型, 并返回这个空对象
function _create(proto){
function F(){}
F.prototype = proto
return new F()
}
10. 千分位分隔符 ⭐
function thousandBitSeparator(num) {
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
});
}
console.log(thousandBitSeparator(-1234567.9012));
11. 实现三角形 ⭐⭐
-
利用边框均分的原理
<style> * { margin: 0; padding: 0; } div { width: 0; height: 0; border-left: 40px solid transparent; border-right: 40px solid transparent; border-top: 40px solid blue; border-bottom: 40px solid transparent; } </style> <body> <div></div> </body>
13. 打乱数组 ⭐⭐
-
sort
数组的sort方法是按照return的值的正负去做排序判定,思路就是使得返回的值随机正负
function fn(arr){ return arr.sort(()=> 0.5 - Math.random()) } let res = fn([1,3,5,7,9]) console.log(res); -
洗牌算法
- 找到数组最后一个元素
- 从数组开头到最后一个元素之间,找到随机的一个数
- 交换两个位置
- 此时最后一个是已经是乱序后的结果
- 执行最后一个元素的索引前移
- 指导指向的索引为0
function randomSortArry(arr){ let len = arr.length for(let i = len-1;i>=0;i--){ var randomIndex = Math.floor(Math.random()*(i+1)) var temp = arr[i] arr[i] = arr[randomIndex] arr[randomIndex] = temp } return arr }
14. 驼峰,下划线相互转换 ⭐⭐⭐
-
驼峰转下划线
//驼峰转下划线 function fn(str){ return str.replace(/([A-Z])/g,'_$1').toLowerCase() } -
下划线转驼峰
function fn2(str){ return str.replace(/_(\w)/g,function(all,letter){ return letter.toUpperCase() }) }
15. 去掉空格
写一个function,清除字符串前后的空格。(兼容所有浏览器)
function Trim(str)
{
return str.replace(/(^\s*)|(\s*$)/g, "");
}