1. 不使用Map, Set, 一次遍历,间复杂度为O(n)
2. NaN判断需要使用isNaN函数,Object对象是引用类型,不需要去重
3. 使用系统内对象存储键值,(字符串和数字分开存储,避免[1, '1']的情况)
Array.prototype.uniq = function () {
  let numberMap = {};
  let stringMap = {};
  let hasNull = false, hasUndefined = false, hasNaN = false;
  let res = [];
  for (let i = 0; i < this.length; i++) {
    let e = this[i];
    let type = Object.prototype.toString.call(e);
    switch (type) {
      case '[object Null]':
        if (!hasNull) {
          res.push(e);
          hasNull = true;
        }
        break;
      case '[object Undefined]':
        if (!hasUndefined) {
          res.push(e);
          hasUndefined = true;
        }
        break;
      case '[object Number]':
        if (isNaN(e)) {
          if (!hasNaN) {
            res.push(e);
            hasNaN = true;
          }
        } else if (!numberMap[e]) {
          res.push(e);
          numberMap[e] = true;
        }
        break;
      case '[object Boolean]':
      case '[object String]':
        if (!stringMap[e]) {
          res.push(e);
          stringMap[e] = true;
        }
        break;
      case '[object Symbol]':
      case '[object Function]':
      case '[object Object]':
      case '[object Array]':
        res.push(e);
        break;
    }
  }
  return res;
};