new

function objectFactory() {
    var obj = new Object(),
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    var ret = Constructor.apply(obj, arguments);
    return typeof ret === 'object' ? ret : obj;
};

Call

Function.prototype.call2 = function(context) {
  context = context ? Object(context) : window
  let fn = Symbol()
  context[fn] = this
	let res = context[fn](...arguments.slice(1))
	delete context[fn]
	return res
}

Apply

Function.prototype.apply2 = function(context, arr) {
	context = context ? Object(context) : window
	let fn = Symbol()
	context[fn] = this
	let res = arr ? context[fn](...arr) : context[fn]()
	delete context[fn]
	return res
}

Function.prototype.apply = function(context = window, args) {
  if (typeof this !== 'function') {
    throw new TypeError('Type Error');
  }
  const fn = Symbol('fn');
  context[fn] = this;

  const res = context[fn](...args);
  delete context[fn];
  return res;
}

Ajax

function GetWebData(URL){
    /**
     * 1:新建XMLHttpRequest请求对象
     */
    let xhr = new XMLHttpRequest()

    /**
     * 2:注册相关事件回调处理函数 
     */
    xhr.onreadystatechange = function () {
        switch(xhr.readyState){
          case 0: //请求未初始化
            console.log("请求未初始化")
            break;
          case 1://OPENED
            console.log("OPENED")
            break;
          case 2://HEADERS_RECEIVED
            console.log("HEADERS_RECEIVED")
            break;
          case 3://LOADING  
            console.log("LOADING")
            break;
          case 4://DONE
            if(this.status == 200||this.status == 304){
                console.log(this.responseText);
                }
            console.log("DONE")
            break;
        }
    }

    xhr.ontimeout = function(e) { console.log('ontimeout') }
    xhr.onerror = function(e) { console.log('onerror') }

    /**
     * 3:打开请求
     */
    xhr.open('Get', URL, true);//创建一个Get请求,采用异步

    /**
     * 4:配置参数
     */
    xhr.timeout = 3000 //设置xhr请求的超时时间
    xhr.responseType = "text" //设置响应返回的数据格式
    xhr.setRequestHeader("X_TEST","time.geekbang")

    /**
     * 5:发送请求
     */
    xhr.send();
}

Extend

function extend() {
  var length = arguments.length;
  var target = arguments[0] || {};
  if (typeof target != "object" && typeof target != "function") {
    target = {};
  }
  if (length == 1) {
    target = this;
    i--;
  }
  for (var i = 1; i < length; i++) {
    var source = arguments[i];
    for (var key in source) {
      // 使用for in会遍历数组所有的可枚举属性,包括原型。
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
  return target;
}

Call

Function.prototype.call = function(context = window, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('Type Error');
  }
  const fn = Symbol('fn');
  context[fn] = this;

  const res = context[fn](...args);
  delete context[fn];
  return res;
}

Promise

function _Promise(executor) {
  this._resolve = [];
  this._reject = [];
  this._catch;

  /*临时保存引用*/
  let self = this;

  this.then = function (resolve, reject) {
    resolve && this._resolve.push(resolve);
    reject && this._reject.push(reject);
    return this;
  };

  this.resolve = function (data) {
    setTimeout(() => {
      let callback = self._resolve.shift();
      self._reject && self._reject.shift();
      let pro;
      callback && (pro = callback(data));
      self._resolve && (pro._resolve = self._resolve);
      self._reject && (pro._reject = self._reject);
      self._catch && (pro._catch = self._catch);
    }, 0);
  };

  this.reject = function (error) {
    setTimeout(() => {
      let callback; 
      self._reject && (callback = self._reject.shift());
      callback && callback(error);
      callback || self._catch(error);
    }, 0);
  };

  this.catch = function (callback) {
    this._catch = callback;
    return this;
  };
  executor(this.resolve, this.reject);
}

function executor(resolve, reject) {
  let rand = Math.random();
  console.log(1);
  console.log(rand);
  if (rand > 0.5) resolve(rand);
  else reject(rand);
}
var p0 = new _Promise(executor);

var p1 = p0.then((value) => {
  console.log("succeed-1");
  return new _Promise(executor);
});

var p3 = p1.then((value) => {
  console.log("succeed-2");
  return new _Promise(executor);
});

var p4 = p3.then((value) => {
  console.log("succeed-3");
  return new _Promise(executor);
});

p4.catch((error) => {
  console.log("error");
});

console.log(2);

Bind

Function.prototype.bind = function(context, ...args) {
  if (typeof this !== 'function') {
    throw new Error("Type Error");
  }
  // 保存this的值
  var self = this;

  return function F() {
    // 考虑new的情况
    if(this instanceof F) {
      return new self(...args, ...arguments)
    }
    return self.apply(context, [...args, ...arguments])
  }
}

Reduce

Array.prototype.myReduce = function(reducer, initialValue) {
    const hasInitial = arguments.length > 1;
    let ret = hasInitial ? initialValue : this[0];
    for (let i = hasInitial ? 0 : 1; i < this.length; i++) {
        ret = reducer.call(undefined, ret, this[i], i, this);
    }
    return ret;
}

// 简版
Array.prototype.myReduce = function(reducer, initialValue) {
    let ret = initialValue;
    for (let i = 0; i < this.length; i++) {
        ret = reducer(ret, this[i], i, this);
    }
    return ret;
}

no-cache,no-store

sizeof object

function roughSizeOfObject( object ) {
    var objectList = [];
    var stack = [ object ];
    var bytes = 0;
    while ( stack.length ) {
        var value = stack.pop();
        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( var i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}

Flat

function flat(arr, depth = Infinity) {
  if(depth <= 0) return arr
  let res = arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flat(cur, depth - 1): [cur])
  }, [])
  return res
}
const arr = [1, [2, [3,[4], 5]]];

叠加求和

function sum(a){
    let temp = function(b){
        return sum(a+b)
    }
    // temp.toString这里写成temp.valueOf也可以
    temp.toString = function(){
        return a
    }
    return temp
}
let ans = sum(1)(2)(3)

Promise.all 实现

Promise.all = function (arr) {
  let res = [];
  return new Promise((resolve, reject) => {
    arr.forEach((item, idx) => {
      item = Promise.resolve(item);
      item
        .then((r, rej) => {
          res[idx] = r;
          if (res.length === arr.length) {
            resolve(res);
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  });
};

科里化

unction add() {
  const _args = [...arguments];
  function fn() {
    _args.push(...arguments);
    return fn;
  }
  fn.toString = function() {
    return _args.reduce((sum, cur) => sum + cur);
  }
  return fn;
}

//Demo:实现add(1)(2)(3)(4)=10; 、 add(1)(1,2,3)(2)=9;

New

// 1. 以ctor.prototype为原型创建一个对象。
// 2. 执行构造函数并将this绑定到新创建的对象上。
// 3. 判断构造函数执行返回的结果是否是引用数据类型,若是则返回构造函数执行的结果,否则返回创建的对象。

function newOperator(ctor, ...args) {
  if (typeof ctor !== 'function') {
    throw new TypeError('Type Error');
  }
  const obj = Object.create(ctor.prototype);
  const res = ctor.apply(obj, args);

  const isObject = typeof res === 'object' && res !== null;
  const isFunction = typeof res === 'function';
  return isObject || isFunction ? res : obj;
}

InstanceOf

const myInstanceof = (left, right) => {
  // 基本数据类型都返回false
  if (typeof left !== 'object' || left === null) return false;
  let proto = Object.getPrototypeOf(left);
  while (true) {
    if (proto === null) return false;
    if (proto === right.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
}

快排

function quickSort(arr){
    if(arr.length<=1){return arr}// 别忘记递归的出口
    var left = []
    var right = []
    var p_index = Math.floor(arr.length/2)
    //一定要去掉已经作为基准数的p值,不然他会把自己又排进去,这样就乱套了。
    var p = arr.splice(p_index, 1)[0]
    for(var i =0 ;i<arr.length;i++){
        if(arr[i]<p){
            left.push(arr[i])
        }else{
            right.push(arr[i])
        }
    }
    return quickSort(left).concat(p,quickSort(right))
}

深拷贝

function clone(target, map = new Map()) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        if (map.get(target)) {
            return map.get(target);
        }
        map.set(target, cloneTarget);
        for (const key in target) {
            cloneTarget[key] = clone(target[key], map);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

K 个有序数组合并

分治 + 递归:时间复杂度 NlogK

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0) {
            return null;
        }
        return merge(lists, 0, lists.length - 1);
    }

    private ListNode merge(ListNode[] lists, int lo, int hi) {
        if (lo == hi) {
            return lists[lo];
        }
        int mid = lo + (hi - lo) / 2;
        ListNode l1 = merge(lists, lo, mid);
        ListNode l2 = merge(lists, mid + 1, hi);
        return merge2Lists(l1, l2);
    }
}

list2tree

var userList = [
  {
    name: "user1",
    age: 18,
    province: "四川",
    city: "成都",
    district: "高新区",
  },
  {
    name: "user2",
    age: 19,
    province: "四川",
    city: "成都",
    district: "天府新区",
  },
  {
    name: "user3",
    age: 20,
    province: "四川",
    city: "南充",
    district: "顺庆区",
  },
  {
    name: "user4",
    age: 22,
    province: "江苏",
    city: "南京",
    district: "鼓楼区",
  },
  {
    name: "user5",
    age: 21,
    province: "江苏",
    city: "南京",
    district: "玄武区",
  },
  {
    name: "user6",
    age: 21,
    province: "江苏",
    city: "镇江",
    district: "京口区",
  },
];

function list2tree(list, path) {
  if (list.length) {
    return list2tree(
      {
        id: "root",
        name: "root",
        children: list,
      },
      path
    );
  }
  if (!path) return list;
  let pathArr = path.split("/");
  let curKey = pathArr[0];
  let resObj = {};
  list.children.forEach((ele) => {
    let v = ele[curKey];
    delete ele[curKey];
    if (resObj[v]) {
      resObj[v].push(ele);
    } else {
      resObj[v] = [ele];
    }
  });
  list.children = Object.keys(resObj).map((item) => {
    let r = list2tree(
      {
        level: curKey,
        name: item,
        children: resObj[item],
      },
      pathArr.slice(1).join("/")
    );
    return r;
  });
  return list;
}

var userTree = list2tree(userList, "province/city");
console.log(userTree);

括号匹配

function bracketPair(str) {
  let pairMap = {
    ")": "(",
    "}": "{",
    "]": "[",
  };
  let quene = [];
  let matchList = Object.keys(pairMap).join(Object.values(pairMap));
  for (let i = 0; i < str.length; i++) {
    if (matchList.indexOf(str[i]) < 0) {
      continue;
    }

    let key = str[i];
    if (pairMap[key]) {
      if (quene.length && quene[quene.length - 1] === pairMap[key]) {
        quene.pop();
      } else {
        return false;
      }
    } else {
      quene.push(key);
    }
  }
  if (quene.length === 0) {
    return true;
  } else {
    return false;
  }
}

链式延时调用

class Task {
  constructor() {
    this.quene = Promise.resolve();
  }
  wait(time) {
    this.quene = this.quene.then(() => {
      return new Promise((res) => {
        setTimeout(res, time * 1000);
      });
    });
    return this;
  }
  log(val) {
    this.quene = this.quene.then(() => {
      console.log(val);
    });
    return this;
  }
}