ES6新增 Set

本文详细介绍了ES6中的Set数据结构,包括其基本语法、操作方法及遍历操作。Set构造函数用于创建唯一值的集合,可去除数组重复成员。Set提供了add、delete、has和clear等操作,且遍历顺序与插入顺序一致。此外,可通过转换为数组来实现Set的map和filter操作,以及并集、交集和差集的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Set

(1)基本语法

Set是ES6新提供的一种数据结构,它类似于数组,但是成员的值都是唯一的,没有重复。

1.Set构造函数

Set本身是一个构造函数,Set函数接受具有iterator接口的数据结构作为参数,用来初始化。以数组为例:

    const set=new Set([1,1,2,2,3,4,5,5]);
    console.log(set);
    //Set [1,2,3,4,5]

可以看出Set结构不会添加重复的值。

2. 去除数组重复成员的两种方法

用扩展运算符(…)(扩展运算符内部使用for…of循环)可以将Set结构转化为数组:

    const set=new Set([1,1,2,2,3,4,5,5]);
    let a=[...set];
    console.log(a);
    //[1,2,3,4,5]

利用Array.from方法(将一个类数组对象或者可遍历对象转换成一个真正的数组):

    let a=[1,1,2,3,3,4,4,5];
    
    let set = new Set(a);
    console.log(set);
    //Set [1,2,3,4,5]
    
    let b=Array.from(set);
    console.log(b);
    //[1,2,3,4,5]
3. 向Set加入值不发生类型转换

向Set中加入值是是不发生类型转换的,所以5和“5”是两个不同的值:

    const set=new Set(["5",5]);
    console.log(set);
    //Set ["5",5]
    
    console.log(set.size);
    //2

Set内部判断两个值是否相等用的算法是"Same-value equality",类似于全等操作符(====),主要的区别是NaN等于自身。
我们先来复习一下全等操作符:它只在两个操作数未经转换就相等的情况下返回true,需要注意的是:

    console.log(null===undefined);
    //false
    console.log(NaN===NaN);
    //false
    console.log({"1":"1"}==={"1":"1"});
    //false  两个对象内存地址不同,总是不全等的
    console.log([1]===[1]);
    //false  两个数组内存地址不同,总是不全等的
    console.log({}==={});
    //false  两个空对象内存地址不同,总是不全等的
    console.log([]===[]);
    //false  两个空数组内存地址不同,总是不全等的
    
    let c=function(){console.log("1")};
    let d=function(){console.log("1")};
    console.log(c===d);
    //false 两个函数内存地址不同,总是不全等的
    
    let e=/at/g;
    let f=/at/g;
    console.log(e===f);
    //false 两个正则表达式内存地址不同,总是不全等的
    
    let date1=new Date();
    let date2=new Date();
    console.log(date1===date2);
    //false 两个Date类型内存地址不同,总是不全等的

全等操作符进行比较时,对象(Date,Array,Obiect,RegExp,Function)通过指针指向的内存中的地址来做比较。
Set和全等操作符不同的地方在于,在Set内部认为NaN等于自身:

    let set = new Set([NaN, NaN]);
    console.log(set);
    //Set [NaN]
    
    console.log(set.size);
    //1

Set和内存地址绑定,只要内存地址不同,就视为两个值:
在Set中两个对象,两个数组,两个函数,两个Date类型,两个正则表达式总是不相等的:

    //对象
    let set = new Set([{"1":"1"}, {"1":"1"}]);
    console.log(set.size);
    //2
    
    //数组
    let set1 = new Set([[1], [1]]);
    console.log(set1.size);
    //2
    
    //空对象
    let set3 = new Set([{}, {}]);
    console.log(set3.size);
    //2

    //空数组
    let set4 = new Set([[], []]);
    console.log(set4.size);
    //2

    //正则表达式
    let e=/at/g;
    let f=/at/g;
    let set5 = new Set([e, f]);
    console.log(set5.size);
    //2

    //Date类型
    let date1=new Date();
    let date2=new Date();
    let set6 = new Set([date1, date2]);
    console.log(set6.size);
    //2

    //函数
    let c=function(){console.log("1")};
    let d=function(){console.log("1")};
    let set7 = new Set([c, d]);
    console.log(set7.size);
    //2

因为对象(Date,Array,Obiect,RegExp,Function)通过指针指向的内存中的地址来做比较。

(2)操作方法
1.add(value)

添加某个值,返回Set结构本身。
由于add方法返回Set结构本身,所以可以采用链式写法:

    let set = new Set();
    set.add(1)
       .add(2)
       .add(3);
    console.log(set);
    // Set [1,2,3]
2.delete(value)

删除某个值,返回一个布尔值,表示删除是否成功。

3.has(value)

返回一个布尔值,表示参数是否为Set成员。

4.clear()

清除所有成员,没有返回值。

(3)遍历操作

Set的遍历顺序就是插入顺序,在Map中遍历顺序也是插入顺序。

1.keys():返回键名的遍历器。
2.values():返回键值的遍历器。
3.entries():返回键值对的遍历器。

由于Set结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

    let set = new Set([1, 2, 3]);
    for (let item of set.keys()) {
        console.log(item)
    }
    //1
    //2
    //3

    for (let item of set.values()) {
        console.log(item)
    }
    //1
    //2
    //3

    for (let item of set.entries()) {
        console.log(item)
    }
    //[1,1]
    //[2,2]
    //[3,3]
    
    for (let item of set) {
        console.log(item)
    }
    //1
    //2
    //3

由上面第四个for…of循环可看出,Set结构的实例默认可遍历,默认遍历器生成函数就是它的values方法(在Map结构中默认遍历器接口是entries方法)。

4.forEach():使用回调函数遍历每个成员,没有返回值。
    let set = new Set([1, 2, 3]);
    set.forEach((value, key) => {
        console.log(value * 2)
    })
    //2
    //4
    //6
遍历方法的应用
1.Set本身没有map和filter方法,可以转为数组,之后使用数组的map和filter方法:
    let set = new Set([1, 2, 3]);
    let set1=new Set([...set].map(x=>x*2));
    console.log(set1);
    //Set [2,4,6]

    let set2=new Set([...set].filter(x=>(x%2===0)));
    console.log(set2);
    // Set [2]
2.实现并集、交集和差集:
    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);

    //并集
    let set1 = new Set([...a,...b]);
    console.log(set1);
    //Set [1,2,3,4]

    //交集
    let set2 = new Set([...a].filter(x => b.has(x)));
    console.log(set2);
    // Set [2,3]

    //差集
    let set3 = new Set([...a].filter(x => !b.has(x)));
    console.log(set3);
    // Set [1]

参考文献:《ECMAScript 6 入门》阮一峰

### ES6新增功能和特性 #### 块级作用域:`let` 和 `const` ES6 引入了两个新的声明变量的关键字——`let` 和 `const`,用于替代传统的 `var` 关键字。`let` 定义的变量具有块级作用域,而 `const` 则定义常量,其值一旦被赋予便不可更改[^1]。 ```javascript // 使用 var for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); } // 输出: 3, 3, 3 // 使用 let for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 100); } // 输出: 0, 1, 2 ``` #### Promise Promise 是一种处理异步操作的对象模型,能够更好地管理回调地狱问题。它有三种状态:待定(pending)、完成(fulfilled)和拒绝(rejected)。通过 `.then()` 方法可以链式调用多个异步操作[^2]。 ```javascript new Promise((resolve, reject) => { resolve('成功'); }).then(value => { console.log(value); // 成功 }); ``` #### 模块化 ES6 支持原生模块化开发,允许开发者通过 `import` 导入外部模块中的内容,并使用 `export` 将内部的内容暴露给其他文件[^2]。 ```javascript // math.js export function add(a, b) { return a + b; } // main.js import { add } from './math'; console.log(add(1, 2)); // 3 ``` #### 类 (`class`) ES6 中引入了类的概念,虽然本质上仍然是基于原型继承,但它提供了一种更加直观的方式来创建对象及其子类[^2]。 ```javascript class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } class Dog extends Animal { speak() { console.log(this.name + ' barks.'); } } const d = new Dog('Rex'); d.speak(); // Rex barks. ``` #### 箭头函数 箭头函数是一种更为简洁的函数表达方式,同时也解决了传统匿名函数中 `this` 绑定的问题。需要注意的是,箭头函数不绑定自己的 `this`,而是捕获外层上下文中的 `this` 值[^2]。 ```javascript function Person() { this.age = 0; setInterval(() => { this.age++; // |this| 正确指向当前实例 }, 1000); } const p = new Person(); ``` #### 解构赋值 解构赋值使得从数组或者对象中提取数据变得非常方便快捷[^2]。 ```javascript const [a, ,b] = [1, 2, 3]; console.log(a, b); // 1, 3 const {name, age} = {name: 'Alice', age: 25}; console.log(name, age); // Alice, 25 ``` #### Symbol Symbol 是一种全新的原始数据类型,在 ES6 中首次出现。每一个 Symbol 实例都应该是独一无二的,这使其非常适合于创建不会与其他属性名冲突的新属性名称。 ```javascript const sym = Symbol('description'); console.log(typeof sym); // symbol ``` #### Set 数据结构 Set 是一种集合数据结构,其中存储的所有元素均唯一无重复。可以通过一系列方法对其进行操作,比如添加、删除以及查询等[^3][^4]。 ```javascript const mySet = new Set(); mySet.add(1); mySet.add(5).add(5); console.log(mySet.size); // 2 console.log(mySet.has(5)); // true mySet.delete(5); console.log(mySet.has(5)); // false ``` #### Array.from() 该静态方法可以从类似数组或可迭代对象返回一个新的数组实例[^4]。 ```javascript const arrayLike = { length: 3 }; const newArray = Array.from(arrayLike); console.log(newArray.length); // 3 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值