手写系列

97 阅读1分钟
  • 发布订阅
const eventHub = {
    hashQueue: {},
    on: (type, fn) => {
        hashQueue[type] = hashQueue[type] || []
        hashQueue[type].push(fn)
    },
    emit: (type, payload) => {
        const queue = hashQueue[type]
        if (!queue) { return }
        queue.map((f) => {
            f(payload)
        })
    },
    off: (type, fn) => {
        const queue = hashQueue[type]
        if (!queue) { return }
        const index = queue.indexOf(fn)
        if (index < 0) { return }
        queue.splice(index, 1)
    },
    once: (type, fn) => {

        const wrapOnce = (...args) => {
            fn()
            eventHub.off(type, fn)
        }
        eventHub.on(type, wrapOnce)
    }
}
  • Ajax
const ajax = (method, url, data, success, fail) => {
  var request = new XMLHttpRequest()
  request.open(method, url);
  request.onreadystatechange = function () {
    if(request.readyState === 4) {
      if(request.status >= 200 && request.status < 300 || request.status === 304) {
        success(request)
      }else{
        fail(request)
      }
    }
  };
  request.send();
}
Promise.myAll = function(list){
  const results = []
  let count = 0
  return new Promise((resolve,reject) =>{
    list.map((item, index)=> {
      item.then(result=>{
          results[index] = result
          count += 1
          if (count >= list.length) { resolve(results)}
      }, reason => reject(reason) )
    })
  })
}

  • DeepClone 解法1
const cheapCopy = (source) => {
  return JSON.parse(JSON.stringify(source));
}; // 不支持Date、RegExp、undefined、Function、引用(环状结构)

const cache = new WeakMap();

const deepClone = (source,cache) => {
if(!cache){
cache = new WeakMap()
}
  if (cache.get(source)) {
    return cache.get(source);
  }
  if (source instanceof Object) {
    let result = undefined;
    if (source instanceof Function) {
      if (source.prototype) {
        result = function () {
          return source.apply(this, arguments);
        };
      } else {
        result = (...args) => {
          return source.call(undefined, ...args);
        };
      }
    } else if (source instanceof Array) {
      result = [];
    } else if (source instanceof Date) {
      result = new Date(source - 0);
    } else if (source instanceof RegExp) {
      result = new RegExp(source.source, source.flags);
    } else {
      result = {};
    }

    cache.set(source, result);
    for (let key in source) {
      if (source.hasOwnProperty(key)) {
        result[key] = deepClone(source[key],cache);
      }
    }
    return result;
  } else {
    return source;
  }
};
  • DeepClone 解法2
const deepClone = (obj, hash = new WeakMap()) => {
  // 日期对象直接返回一个新的日期对象
  if (obj instanceof Date) {
    return new Date(obj);
  }
  //正则对象直接返回一个新的正则对象     
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  //如果循环引用,就用 weakMap 来解决
  if (hash.has(obj)) {
    return hash.get(obj);
  }
  // 获取对象所有自身属性的描述
  let allDesc = Object.getOwnPropertyDescriptors(obj);
  // 遍历传入参数所有键的特性
  let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)

  hash.set(obj, cloneObj)
  for (let key of Reflect.ownKeys(obj)) {
    if (typeof obj[key] === 'object' && obj[key] !== null) {
      cloneObj[key] = deepClone(obj[key], hash);
    } else {
      cloneObj[key] = obj[key];
    }
  }
  return cloneObj
}

获取对象所有自身属性的描述 let allDesc = Object.getOwnPropertyDescriptors(obj);

遍历传入参数所有键的特性 let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)

  • 数组去重

const uniq = function(a){
  const map = new Map()
  for(let i=0;i<a.length;i++){
    let number = a[i] // 1 ~ 3
    if(number === undefined){continue}
    if(map.has(number)){
      continue
    }
    map.set(number, true)
  }
  return [...map.keys()]
}

  • 真正的 事件委托

function delegate(element, eventType, selector, fn) {
	element.addEventListener(eventType, e => {
	  let el = e.target
	  while (!el.matches(selector)) {
	    if (element === el) {
	      el = null
	      break
	    }
	    el = el.parentNode
	  }
	  el && fn.call(el, e, el)
	})
	return element
}

delete(ul, 'click', 'li', f1)