常用工具函数之手写系列
- 节流函数
function throttle(fn,wait){
let time = 0;
return function(...args){
let now = new Date();
if(now-time > wait){
time = now;
fn.apply(this,args)
}
}
}
- 防抖函数
function debounce(fn,wait){
let time = null;
return function(...args){
if(time){clearTimeout(time)}
tiem = setTimeout(function(){
fn.apply(this,args);
},wait)
}
}
- 深拷贝
function deepclone(obj){
if(obj == null){
return obj
}
if(typeof obj !== 'object'){
return obj
}
if(typeof obj === 'function'){
return obj
}
if(obj instanceof Date){
return new Date(obj)
}
if(obj instanceof RegExp){
return new RegExp(obj)
}
let cloneobj = new obj.constructor;
for(let key in obj){
if(obj.hasOwnProperty(key)){
cloneobj[key] = deepclone(obj[key])
}
}
return cloneobj
}
- 模版字符串替换
let name = 'LJDOM',age=18;
let str = "${name}今年${age}岁了"
function replace(str){
return str.replace(/\$\{([^}]+)\}/g,function(mathed,key){
return eval(key)
})
}
console.log(replace(str))
Promise
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function Promise(execute){
let self = this;
self.status = PENDING;
self.value = undefined;
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value){
if(value instanceof Promise){
return value.then(resolve,reject)
}
setTiemout(function(){
if(self.status === PENDING){
self.status = FULFILLED;
self.value = value;
self.onResolvedCallbacks.forEach(cb=>cb(value))
}
})
}
function reject(reason){
setTiemout(function(){
if(self.status === PENDING){
self.status = REJECTED;
self.value = reason;
self.onRejectedCallbacks.forEach(cb=>cb(reason))
}
})
}
try{
execute(resolve,reject)
}catch(e){
reject(e)
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError('循环引用'))
}
let called = false;
if(x instanceof Promise){
if(x.status === PENDING){
x.then(function(y){
resolvePromise(promise2,y,resolve,reject);
},reject)
}else{
x.then(resolve,reject)
}
}else if(x !== null &&((typeof x === "function")||(typeof x === 'object'))){
try{
let then = x.then;
if(typeof then === "function"){
if(called){return}
called =true;
then.call(x,function(y){
resolvePromise(promise2,y,resolve,reject)
},function(err){
if(called){return}
called =true;
reject(err)
})
}else{
if(called){return}
called =true;
resolve(x)
}
}catch(e){
if(called){return}
called =true;
reject(e)
}
}else{
if(called){return}
called =true;
resolve(x)
}
}
Promise.prototype.then = function(onFulfilled,onRejected){
onFulfilled = typeof onFulfilled === "function"?onFulfilled:function(value){return value}
onRejected = typeof onRejected === "function"?onRejected:function(reason){throw reason}
let self = tihs;
let promise2;
if(self.status === FULFILLEND){
return promise2 = new Promise(function(resolve,reject){
try{
let x = onFulfilled(self.value)
if(x instanceof Promise ){
resolvePromise(promise2,x,resolve,reject)
}
}catch(e){
reject(e)
}
})
}
if(self.status === REJECTED){
return promise2 = new Promise(function(resolve,reject){
try{
let x = onRejected(self.value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
})
}
if(self.status === PENDING){
return promise2 = new Promise(function(resolve,reject){
self.onResolvedCallbacks.push(function(){
try{
let x = onFulfilled(self.value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
});
self.onRejectedCallbacks.push(function(){
try{
let x = onRejected(self.value)
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
});
})
}
}
Promise.prototype.catch=function(onReject){
this.then(null,onReject)
}
function gn(tims,cb){
let result = [],count=0;
return function(i,data){
result[i] = data
if(++count === tims){
cb(result)
}
}
}
Promise.all=function(promises){
return new Promise(function(resolve,reject){
let don = gn(promises.length,resolve)
for(let i = 0;i<promises.length;i++){
promises[i].then(function(data){
don(i,data);
},reject)
}
})
}
Promise.race=function(promises){
return new Promise(function(resolve,reject){
for(let i = 0;i<promises.length;i++){
promises[i].then(resolve,reject)
}
})
}
- 待续。。。