Vue.js设计与实现#查漏补缺(2-4-1)

48 阅读3分钟

查漏补缺

最近看《Vue.js设计与实现》响应系统之响应系统的作用与实现的时候,倍感吃力,原因是 JavaScript 基础不扎实。比如:ProxySetWeakMap ...

大神说:学习的过程就是查漏补缺

Set

1. 概述

ES6 新增的数据结构。类似于数组的对象,但是成员的值都是唯一的。

类似于数组的对象:Set 结构没有键名,只有键值。或者说键名和键值是同一个值。

  • [...new Set(Array)] 数组去重的实现原理。
  • [...new Set(String)].join('') 字符串去重。

扩展运算符(...)内部使用 for...of 循环。

Set 本身是一个构造函数,用来生成 Set 数据结构。

const set = new Set()

Set 函数可以接受一个数组或者具有 iterable 接口的其他数据结构作为参数,用来初始化。

// 数组参数
const set = new Set([1, 2, 3, 4, 4])

// 类似数组的对象作为参数
const set = new Set(document.querySelectorAll('div'))

Set 内部判断两个值是否不同,使用的算法是 Same-value-zero equality,类似于精确相等运算符(===),但Set 加入值时认为 NaN 等于自身,而精确相等运算符认为 NaN 不等于自身。

const set = new Set()

const val1 = NaN
const val2 = NaN

const obj1 = {}
const obj2 = {}

const arr1 = []
const arr2 = []

const num1 = 2
const num2 = '2'

set.add(val1)
set.add(val2)

set.add(obj1)
set.add(obj2)

set.add(arr1)
set.add(arr2)

set.add(num1)
set.add(num2)

console.log(set) // {NaN, {...}, {...}, Array(0), Array(0), 2, '2'}

2. 属性和方法

Set 实例的属性:

  • Set.prototype.constructor:构造函数,默认就是 Set 函数。
  • Set.prototype.size:返回 Set 实例的成员总数。

Set 实例的方法:

  • 操作方法:用于操作数据。

    • Set.prototype.add(value):添加某个值,返回 Set 结构本身。
    • Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    • Set.prototype.has(value):返回一个布尔值,表示该值是否为 Set 的成员。
    • Set.prototype.clear():清除所有成员,没有返回值。
  • 遍历方法:用户遍历成员。

    • Set.prototype.keys():返回键名的遍历器。
    • Set.prototype.values():返回键值的遍历器。
    • Set.prototype.entries():返回键值对的遍历器。
    • Set.prototype.forEach():使用回调函数遍历每个成员。

    Set 遍历顺序就是插入顺序。

    Set 结构没有键名,只有键值。或者说键名和键值是同一个值

    • keys()values() 方法的行为完全一致。
    • entries() 方法每次返回一个包含两个完全相等的成员的数组。

3. 应用

  1. 去重

    • [...new Set(Array)] 数组去重。

    • [...new Set(String)].join('') 字符串去重。

    • Array.from() 方法可以将 Set 结构转为数组。—— 数组去重的另一种方法的实现原理。

      function dedupe(array) {
          return Array.from(new Set(array))
      }
      
      // 调用
      dedupe([1, 1, 2, 3]) // [1, 2, 3]
      
  2. 实现并集(Union)、交集(Intersect)和差集(Difference

    const a = new Set([1, 2, 3])
    const b = new Set([4, 3, 2])
    
    // 并集
    const union = new Set([...a, ...b])
    // 交集
    const intersect = new Set([...a].filter(ctx => b.has(ctx)))
    // a 相对于 b的差集
    const diffrence = new Set([...a].filter(ctx => !b.has(ctx)))
    
  3. 间接同步改变原来的 Set 结构

    • 利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构。
      let set = new Set([1, 2, 3])
      
      set = new Set([...set].map(val => val * 2))
      
    • 利用 Array.from() 方法。
      let set = new Set([1, 2, 3])
      
      set = new Set(Array.from(set, val => val * 2))        
      

参考资料