前端手写练习
| Promise | Deepcopy | debounce | throttle | EventEmitter | call\bind\apply |
|---|
| 异步 | 深拷贝 | 防抖 | 节流 | 发布订阅 | this绑定 |
- 手写Promise
class Promise{
constructor(callback){
this.status = 'pending';
this.answer = undefined;
this.succeArr = [];
this.failArr = [];
this.resolve = (val)=>{
if(this.status === 'fullfiled') {
this.status === 'fullfiled';
this.answer = val;
this.succeArr.map(item=>item())
}
};
this.reject = (val)=>{
if(this.status === 'reject') {
this.status === 'reject'
this.answer = val
this.failArr.map(item=>item())
}
};
try{
callback(this.resolve.bind(this),this.reject.bind(this))
} catch(err) {
this.reject(err)
}
}
then(suc,fail){
if(this.status === 'fullfiled') {
suc(this.answer);
}
if(this.status === 'reject') {
fail(this.answer);
}
if(this.status === 'pending') {
this.succeArr.push(()=>suc(this.answer))
this.failArr.push(()=>fail(this.answer))
}
}
all(promiseArr){
let index = 0;
let data = []
return new Promise((resolve,reject)=>{
for (const i in promiseArr) {
let promise = promiseArr[i];
index++;
promise().then(res=>{
data[i] = res
if(index===promiseArr.length){
resolve(data)
}
}).catch(err=>{
reject(err)
})
}
})
}
}
- 手写深拷贝
function deepcopy(obj,hash= new WeakMap()) {
if(obj!==null||typeof obj !== 'Object'){
return obj
}
if(hash.get(obj)) return hash.get(obj)
let cloneObj = new obj.construtor()
hash.set(obj,cloneObj)
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const element = obj[key];
cloneObj[key] = deepcopy(element,hash)
}
}
return cloneObj
}
- 防抖
function debounce(func,delay){
let timer;
return function() {
if(timer){
clearTimeout(timer)
}
setTimeout(()=>{
timer = func()
},delay)
}
}
- 节流
function throttle(fn,delay) {
let flag = true;
return ()=>{
if(!flag) return
setTimeout(() => {
if(flag) {
fn()
flag = false
}
}, delay);
}
}
- 发布订阅
class EventEmitter {
public event:any
constructor(){
this.event={}
}
addListener(type,callback){
if(!this.event[type]){
this.event[type]=[callback]
}else{
this.event[type].push(callback)
}
}
removeListener(type,callback){
if(this.event[type]){
this.event[type]=this.event[type].filter(item=>item!==callback)
}else{
return
}
}
emit(type,params){
this.event[type]&&this.event[type].forEach((fn) => fn.apply(this, params))
}
once(type,callback){
function onceFn(params) {
callback();
this.removeListener(type,onceFn)
}
this.addListener(type,onceFn)
}
}
- call\bind\apply
Function.protoType.call=function(obj,arg){
let ctx = obj || window
let symbKey = symbol();
ctx[symbKey] = this;
let res = ctx[symbKey](...arg);
delete ctx[symbKey];
return res
}
Function.protoType.bind=function(){
let instance = (context===null ? window : this)
return function(){
return instance.call(context,...params)
}
}
Function.protoType.apply=function(context,args=[]){
let cxt = context || window;
const specialKey = Symbol();
cxt[specialKey] = this;
let result = args.length>0? cxt[specialKey](...args):cxt[specialKey]();
delete cxt[specialKey];
return result;
}