一、数组相关

去重

    1. 利用 indexOf()方法,如果查询到则返回查询到的第一个结果在数组中的索引,如果查询不到则返回-1
var arr = [1, 3, 6, 2, 10]
var newArr = []
for (var i = 0; i < arr.length; i++) {
  if (newArr.indexOf(arr[i]) === -1) {
    newArr.push(arr[i])
  }
}

扩展:includes、filters 等都可以

    1. 利用 ES6 Set 去重
function unique(arr) {
  return Array.from(new Set(arr))
}

// [...new Set(arr)]

注意:这种方法还无法去掉“{}”空对象

    1. 利用 for 嵌套 for,然后 splice 去重
function unique(arr) {
  for (var i = 0; i < arr.length; i++) {
    for (var j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1) // 删除
        j--
      }
    }
  }
  return arr
}

注意:NaN 和{}没有去重,两个 null 直接消失了

二、实现 new 操作符

实现一个 new 操作符的具体实现步骤:

  • 首先函数接受不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用
  • 然后内部创建一个空对象 obj
  • 因为 obj 对象需要访问到构造函数原型链上的属性,所以我们通过 setPrototypeOf 将两者联系起来。这段代码等同于 obj.proto = Con.prototype
  • 将 obj 绑定到构造函数上,并且传入剩余的参数
  • 判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 obj
/**
 * 创建一个new操作符
 * @param {*} Con 构造函数
 * @param  {...any} args 构造函数中传的参数
 */
function createNew(Con, ...args) {
  let obj = {} // 创建一个对象,因为new操作符会返回一个对象
  Object.setPrototypeOf(obj, Con.prototype) // 将对象与构造函数原型链接起来
  // obj.__proto__ = Con.prototype
  let result = Con.apply(obj, ...args) // 将构造函数中的this指向这个对象,并传递参数
  return result instanceof Object ? result : obj
}

三、实现 instanceof 操作符

instanceof 是用来检测一个对象在其原型链中是否存在一个构造函数的 prototype 属性

function instanceof (left, right) {
  let proto = left.__proto__;
  let prototype = right.prototype;
  while(true) {
    if(proto === null) return false
    if(proto === prototype) return true
    proto = proto.__proto__
  }
}