JavaScript 高频手写代码

吐槽君 分类:javascript

实现 REDUCE

Array.prototype.reduce = function (callback, intialVal) { 
  var self = this,
      i = 0,
      len = self.length;
      console.log(Object.prototype.toString.call(self))
  if( !(self instanceof Array)) throw new TypeError(self+".reduce is not a function");

  if( !(/^(function)$/.test(typeof callback)) ) throw new TypeError("callback must be an function");

  // 没有初始值
  if(typeof intialVal === undefined) {
      i = 1;
      intialVal = self[0];
  }
  // 每次循环都去执行一次回调函数
  for(; i<len; i++) {
      intialVal = callback(intialVal, self[i], i);
  }
  return intialVal;
}
 

实现 CALL

Function.prototype.call = function call(context, ...params) {
  let self = this,
      result = null,
      key = Symbol('KEY');

      context == null ? context = window : null;
      !/^(object|function)$/.test(typeof context)? Object(context) : null;
      context[key] = self;
      result = context[key](...params);
      delete context[key];
      return result;
}
 

实现 APPLY

Function.prototype.apply = function call(context, params) {
  let self = this,
      result = null,
      key = Symbol('KEY'),
      args = [],
      i = 0,
      len = params.length;

  context == null ? context = window : null;
  !/^(object|function)$/.test(typeof context)? Object(context) : null;

  if(typeof params !== 'undefined'&&
  Object.prototype.toString.call(params) !== '[object Array]' ) 
  throw new TypeError('CreateListFromArrayLike called on non-object');

  context[key] = self;
  if (!params) {
      result = context.fn();
  }else {
      // result = context[key](...params);
      for (,i < len; i++) {
          args.push('params[' + i + ']');
      }
      result = eval('context.fn(' + args + ')')
  }   

  delete context.fn;
  return result;
}
 

实现 BIND

Function.prototype.bind = function bind(context) {
  var params = [].slice.call(arguments, 1),// 截取除第一个参数之外的参数
      self = this;
      
  return function proxy() {
      var outerArgs = [].slice.call(arguments).concat(params);
      return self.apply(context, outerArgs);
  }
}
 

实现 NEW

function _new(Ctor) { 
  var reg = /^(object|function)$/i,
        params,
        obj,
        result;
  if( typeof Ctor !== 'function' || 
      !reg.test(typeof Ctor.prototype)) throw new TypeError('Ctor is not a constructor')

  var params = [].slice.call(arguments, 1),
      obj = Object.create(Ctor.prototype),
      result = null;

    result = Ctor.call(obj, params);

  if(reg.test(typeof result)) return result;

  return obj;
}
 

实现防抖

function debounce(func, wait, immediate) { 
  if(typeof func !== 'function') throw new TypeError('func must be an function');
  只有一个, 那么wait赋值默认值 500
  if(typeof wait === 'undefined') wait = 500;
  if(typeof wait === 'boolean') {
    immediate = wait;
    wait = 1500; // 默认值
  };
  if(typeof immediate !== 'boolean') immediate = false;

  let timer = null;
  return function proxy(...args) {
    let self = this,
        now = immediate && !timer;
     timer = setTimeout(()=>{
      timer = null;
      !immediate?func.call(self, ...args):null;
    }, wait);

    now?func.call(self, ...args) : null;
  };
 };
 

实现节流

function throttle(func, wait) {
  if(typeof func !== 'function') throw new TypeError('func must be an function');
  if(typeof wait === 'undefined') wait = 500;

  let timer = null,
      previous = 0; // 记录上一次操作的时间

  return function proxy(...param) { 
    let self = this,
        now = new Date(),
        remaining = wait - ( now - previous ); 
        if(remaining<=0) {
          clearTimeout(timer);
          timer = null;
          previous = now;
          func.call(self, ...param);
        } else if(!timer){
          timer = setTimeout(()=>{
               timer = null;
          
                clearTimeout(timer);
                func.call(self, ...param);
                previous = new Date();
          }, remaining);
        }
   };
};
 

实现数组/对象的浅拷贝

  • 数组的浅拷贝
let copyArr = [...arr];
 
let copyArr = arr.concat();
 
let copyArr = arr.slice();
 
  • 对象的浅拷贝
let copyObj = {...obj}
 
let copyObj = Object.assign({}, obj1)
 

以上两种方案都包含了 Symbol 属性的处理

for in 循环,不支持 Symbol 属性
 

回复

我来回复
  • 暂无回复内容