参考资料:《JavaScript高级程序设计 第3版》 《ES6标准入门》 菜鸟 W3School
你可以点击这里查看重新排版与整理后的版本
目录
数组方法
汇总
归类 | 方法 | 描述 |
检测数组 | isArray() | Array.isArray(value)准确检测数组 |
转换方法 这三个是所有对象都具有的方法 | valueOf() | 返回数组对象的原始值(一般不会显示调用);返回数组本身 |
toString() | 把数组转换为字符串,并返回结果,每一项以逗号分割。 | |
toLocalString() | 把数组转换为本地数组,并返回结果。 | |
栈方法 | push() | 数组末尾添加项 |
pop() | 弹出数组末尾数据并返回该值 | |
队列方法 | shift() | 移除数组中第一个项并返回该项 |
unshift() | 数组前端添加项 | |
重排序方法 | reverse() | 反转数组顺序 |
sort() | 排序数组,默认升序 | |
操作方法 | concat() | 基于当前数组中的所有项创建一个新数组.这个方法会先创建当前数组一个副本,然后将接收到的参数 添加到这个副本的末尾,最后返回新构建的数组 |
slice() | 基于当前数组中的一或多个项创建一个新数组 | |
splice() | 删除数组中的项或往数组中插入项 | |
位置方法 | indexOf() | 这两个方法都接收两个参数:要查找的项和(可选的)表示查找起点位置的索引 indexOf()从数组开头开始查找 lastIndexOf()从数组末尾开始向前查找 |
lastIndexOf() | ||
迭代方法 迭代方法都不会修改原数组每个方法都接收两个参数:要在每一项上运行的函数和 (可选的)运行该函数的作用域对象——影响 this 的值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。 | every() | 对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true。 |
some() | 对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true。 | |
filter() | 对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组 | |
forEach() | 对数组中的每一项运行给定函数。这个方法没有返回值。 | |
map() | 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。 | |
归并方法 | reduce() reduceRight() | 迭代数组的所有项,然后构建一个最终返回的值 |
ES6新增 | 扩展运算符(spread) | 将一个数组转为用逗号分隔的参数序列 console.log(...[1,2,3]) //1 2 3 |
of() | 将一组值转换为数组,用于弥补构造函数Array()的不足 | |
find() findIndex() | 找出第一个符合条件的数组成员/下标 | |
from()
| 用于将两类对象转换为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)对象 | |
fill() | 使用给定值填充数组 [‘a’,’b’,’c’].fill(7, 1, 2) // [‘a’,’1’,’c’] | |
includes() | 检测数组是否包含某个给定的值 | |
其他 | join(seperator) | 把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。seperator是可选参数,默认使用','分隔 |
细节
1.toString()和toLocalString()
toLocalString()是调用每个数组元素的 toLocaleString() 方法,然后使用地区特定的分隔符把生成的字符串连接起来,形成一个字符串。
toString()方法获取的是String(传统字符串),而toLocaleString()方法获取的是LocaleString(本地环境字符串)。
如果你开发的脚本在世界范围都有人使用,那么将对象转换成字符串时请使用toString()方法来完成。
LocaleString()会根据你机器的本地环境来返回字符串,它和toString()返回的值在不同的本地环境下使用的符号会有微妙的变化。
所以使用toString()是保险的,返回唯一值的方法,它不会因为本地环境的改变而发生变化。如果是为了返回时间类型的数据,推荐使用toLocaleString()。若是在后台处理字符串,请务必使用toString()。
2.sort()
比较函数(sort)接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。
function compare(value1, value2){
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
这个比较函数可以适用于大多数数据类型,只要将其作为参数传递给 sort()方法即可
var values = [0, 1, 5, 10, 15];
values.sort(compare);
如果要使用降序将返回-1 和 1的顺序调换即可。
对于数值类型或者其 valueOf()方法会返回数值类型的对象类型,可以使用一个更简单的比较函数。这个函数只要用第二个值减第一个值即可
function compare(value1, value2) { return value2 - value1; }
由于比较函数通过返回一个小于零、等于零或大于零的值来影响排序结果,因此减法操作就可以适当地处理所有这些情况
3.concat()与slice()与splice()
在没有给 concat()方法传递参数的情况下,它只是复制当前数组并返回副本。如果传递给 concat()方法的是一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾。
var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,black,brown
slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。注意,slice()方法不会影响原始数组。
var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
splice()方法
删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。例如,splice(0,2)会删除数组中的前两项。
插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。例如
splice(2,0,"red","green")会从当前数组的位置 2 开始插入字符串"red"和"green"。
替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如, splice (2,1,"red","green")会删除当前数组位置 2 的项,然后再从位置 2 开始插入字符串 "red"和"green"。(先删除再插入)
splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)
4.迭代方法的使用
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]
['1', '2', '3'].map(parseInt) 答案是多少?
答案 [1, NaN, NaN]
map会给函数传递3个参数: (item, index, array)
parseInt接收两个参数(sting, radix),其中radix代表进制。省略 radix 或 radix = 0,则数字将以十进制解析
因此,map 遍历 ["1", "2", "3"],相应 parseInt 接收参数如下
parseInt('1', 0); // 1
parseInt('2', 1); // NaN
parseInt('3', 2); // NaN
parseInt("10"); //返回 10
parseInt("19",10); //返回 19 (10+9)
parseInt("11",2); //返回 3 (2+1)
parseInt("17",8); //返回 15 (8+7)
parseInt("1f",16); //返回 31 (16+15)
5.归并方法的使用
reduce()方法从数组的第一项开始,逐个遍历到最后。而 reduceRight()则从数组的最后一项开始,向前遍历到第一项。 这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传给 reduce()和 reduceRight()的函数接收 4 个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第 一个参数是数组的第一项,第二个参数就是数组的第二项。
使用 reduce()方法可以执行求数组中所有值之和的操作,比如:
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
第一次执行回调函数,prev 是 1,cur 是 2。第二次,prev 是 3(1 加 2 的结果),cur 是 3(数组 的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果字符串方法
6.检测数组的方式
const myArray = [1, 3, 5, 7, 9]
const myValue = 1
// 1.使用instanceof, 判断该对象的原型链上是否有Array.prototype
console.log(myArray instanceof Array) // true
console.log(myValue instanceof Array) // false
// 2.使用constructor, 找到该对象的构造函数?
console.log(myArray.constructor === Array) // true
console.log(myValue.constructor === Array) // false
// 3.使用Object.prototype.toString.call(arr) === '[object Array]'
// 即改变this指向, 调用Object原型上的toString方法
function myIsArray(arr) {
return Object.prototype.toString.call(arr)
}
let obj = {}
let fn = function() {}
console.log(myIsArray(myArray)) // [object Array]
console.log(myIsArray(myValue)) // [object Number]
console.log(myIsArray(obj)) // [object Object]
console.log(myIsArray(fn)) // [object Function]
// 4.ES5定义了Array.isArray
console.log(Array.isArray(myArray)) // true
字符串方法
汇总(部分)
方法 | 描述 |
charAt(index) | 返回指定位置的字符 |
charCodeAt(index) | 返回指定位置的字符的Unicode编码 |
codePointAt(index) ---ES6 | 返回指定位置的字符的码点(能正确处理4字节) |
fromCharCode() | 接受一个或多个字符编码并转换成字符串 |
concat() | 拼接字符串 |
slice(start, end) | 提取字符串的片断,并在新的字符串中返回被提取的部分。 |
substr(start, length) | 从起始索引号提取字符串中指定数目的字符。 |
substring(start, stop) | 提取字符串中介于两个指定下标之间的字符,和slice类似只是传递参数为负数时不同 |
indexOf(searchValue, fromindex) lastIndexOf(searchValue, fromindex) | 从一个字符串中搜索给定的子字符串,然后返子字符串的位置(如果没有找到该子字符串,则返回-1)区别是从前还是从后开始 |
trim() 有些浏览器还支持非标准的trimLeft()和trimRgiht()方法 | 这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果 |
toLowerCase()、toLocaleLowerCase()、toUpperCase()、 toLocaleUpperCase() | 大小写转换,Lcalel是针对特定地区的实现。一般来说,在不知道自己的代码将在哪种语言环境中运行的情况下,还是使用针对地区的方法更稳妥一些 |
match(searchValue / RegExp) | 根据是否全局搜索,返回值会不同 |
search(searchValue / RegExp) | 返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1。而且,search()方法始终是从字符串开头向后查找模式。 |
replace(regexp/substr,replacement) | 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。 |
split(separator,howmany) | 基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中 |
localeCompare(targetString) | 用本地特定的顺序来比较两个字符串。 |
细节
1.字符方法:用于访问字符串中特定字符
charAt(index):返回指定位置的字符
charCodeAt(index):返回指定位置的Unicode编码
ES6新增:codePointAt(index): 能够正确处理4个字节储存的字符,返回指定索引出一个字符的码点。codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。
fromCharCode()方法
String 构造函数本身还有一个静态方法:fromCharCode()。这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串。从本质上来看,这个方法与实例方法 charCodeAt() 执行的是相反的操作。来看一个例子:
alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"
在这里,我们给 fromCharCode()传递的是字符串"hello"中每个字母的字符编码。
2.字符串操作方法
concat():拼接多个字符串,一般用“+”代替
slice()、substr()和 substring():三个基于子字符串创建新字符串的方法:
slice(start,end):
参数start:要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。
参数end:紧接着要抽取的片段的结尾的下标。若未指定此参数,则要提取的子串包括 start 到原字符串结尾的字符串。如果该参数是负数,那么它规定的是从字符串的尾部开始算起的位置。
(负值都是从尾部开始算起)
substr(start, length):
参数start:必需。要抽取的子串的起始下标。必须是数值。如果是负数,那么该参数声明从字符串的尾部开始算起的位置。
参数length:可选。子串中的字符数。必须是数值。如果省略了该参数,那么返回从 stringObject 的开始位置到结尾的字串。
substring(start,stop):提取字符串中介于两个指定下标之间的字符。
参数start:必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。
参数stop:可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾。
var stringValue = "hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3, 7)); //"lo w"
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3, 7)); //"lo worl"
这个例子比较了以相同方式调用 slice()、substr()和 substring()得到的结果,而且多数情况下的结果是相同的。在只指定一个参数 3 的情况下,这三个方法都返回"lo world",因为"hello" 中的第二个"l"处于位置 3。而在指定两个参数 3 和 7 的情况下,slice()和 substring()返回"lo w" ("world"中的"o"处于位置 7,因此结果中不包含"o"),但 substr()返回"lo worl",因为它的第二个参数指定的是要返回的字符个数。
var stringValue = "hello world";
alert(stringValue.slice(-3)); //"rld"
alert(stringValue.substring(-3)); //"hello world"
alert(stringValue.substr(-3)); //"rld"
alert(stringValue.slice(3, -4)); //"lo w"
alert(stringValue.substring(3, -4)); //"hel"
alert(stringValue.substr(3, -4)); //""(空字符串)
在传递给这些方法的参数是负值的情况下,它们的行为就不尽相同了。其中,slice()方法会将传入的负值与字符串的长度相加,substr()方法将负的第一个参数加上字符串的长度,而将负的第二个参数转换为 0。最后,substring()方法会把所有负值参数都转换为 0。
3.字符串位置方法
indexOf(searchValue, fromindex)和 lastIndexOf(searchValue, fromindex)
这两个方法都是从一个字符串中搜索给定的子字符串,然后返子字符串的位置(如果没有找到该子字符串,则返回-1)。 这两个方法的区别在于:indexOf()方法从字符串的开头向后搜索子字符串,而 lastIndexOf()方法是从字符串的末尾向前搜索子字符串。
这两个方法都可以接收可选的第二个参数,表示从字符串中的哪个位置开始搜索。
indexOf()会从该参数指定的位置向后搜索,忽略该位置之前的所有字符;而 lastIndexOf()则会从指定的位置向前搜索,忽略该位置之后的所有字符。
可以通过循环调用 indexOf()或 lastIndexOf()来找到所有匹配的子字符串,如下 面的例子所示
var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var positions = new Array();
var pos = stringValue.indexOf("e");
while(pos > -1){
positions.push(pos);
pos = stringValue.indexOf("e", pos + 1);
}
console.log(positions); //"3,24,32,35,52"
4.trim()方法
这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果
var stringValue = " hello world ";
var trimmedStringValue = stringValue.trim();
console.log(stringValue); //" hello world "
console.log(trimmedStringValue); //"hello world"
由于 trim()返回的是字符串的副本,所以原始字符串中的前置及后缀空格会保持不变。
Firefox 3.5+、Safari 5+ 和 Chrome 8+还支持非标准的还支持非标准的 trimLeft()和 trimRight()方法,分别用于删除字符串开头和末尾的空格.
5.字符串的模式匹配方法
match()方法只接受一个参数,要么是一个正则表达式,要么是一个 RegExp 对象
match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。
如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。
注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。
var text = "cat, bat, sat, fat";
var pattern = /.at/;
//与 pattern.exec(text)相同
var matches = text.match(pattern);
console.log(matches.index); //0
console.log(matches[0]); //"cat"
console.log(pattern.lastIndex); //0
console.log(matches); // ['cat', index:0, input:'cat,bat,sat,fat' ]
var text = "cat, bat, sat, fat";
var pattern = /.at/g;
var matches = text.match(pattern);
console.log(matches.index); //undefined
console.log(matches[0]); //"cat"
console.log(pattern.lastIndex); //0
console.log(matches); // ['cat','bat','sat','fat']
search()
另一个用于查找模式的方法是 search()。这个方法的唯一参数与 match()方法的参数相同:由字符串或 RegExp 对象指定的一个正则表达式。search()方法返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1。而且,search()方法始终是从字符串开头向后查找模式。
replace()
这个方法接受两个参数:第一个参数可以是一个 RegExp 对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(g)标志,如下所示
var text = "cat, bat, sat, fat";
var result = text.replace("at", "ond");
console.log(result); //"cond, bat, sat, fat"
result = text.replace(/at/g, "ond");
console.log(result); //"cond, bond, sond, fond"
如果第二个参数是字符串,那么还可以使用一些特殊的字符序列,将正则表达式操作得到的值插入到结果字符串中。下表列出了 ECMAScript 提供的这些特殊的字符序列
var text = "cat, bat, sat, fat";
result = text.replace(/(.at)/g, "word ($1)");
alert(result); //word (cat), word (bat), word (sat), word (fat)
在此,每个以"at"结尾的单词都被替换了,替换结果是"word"后跟一对圆括号,而圆括号中是被字符序列$1 所替换的单词。
replace()方法的第二个参数也可以是一个函数。在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递 3 个参数:模式的匹配项、模式匹配项在字符串中的位置和原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项……,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串。这个函数应该返回一个字符串,表示应该被替换的匹配项。使用函数作为 replace()方法的第二个参数可以实现更加精细的替换操作,请看下面这个例子。
function htmlEscape(text){
return text.replace(/[<>"&]/g, function(match, pos, originalText){
switch(match){
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
case "\"":
return """;
}
});
}
alert(htmlEscape("<p class=\"greeting\">Hello world!</p>"));
//<p class="greeting">Hello world!</p>
这里,我们为插入 HTML 代码定义了函数 htmlEscape(),这个函数能够转义 4 个字符:小于号、 大于号、和号以及双引号。实现这种转义的最简单方式,就是使用正则表达式查找这几个字符,然后定义一个能够针对每个匹配的字符返回特定 HTML 实体的函数
6.localeCompare()方法
这个方法比较两个字符串,并返回下列值中的一个:
- 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1,具体的值要视实现而定);
- 如果字符串等于字符串参数,则返回 0;
- 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(大多数情况下是 1,具体的值同样要视实现而定)。
例子如下:
var stringValue = "yellow";
alert(stringValue.localeCompare("brick")); //1
alert(stringValue.localeCompare("yellow")); //0
alert(stringValue.localeCompare("zoo")); //-1
因为 localeCompare()返回的数值取决于实现,所以最好是像下面例子所示的这样使用这个方法。
function determineOrder(value) {
var result = stringValue.localeCompare(value);
if (result < 0){
alert("The string 'yellow' comes before the string '" + value + "'.");
} else if (result > 0) {
alert("The string 'yellow' comes after the string '" + value + "'.");
} else {
alert("The string 'yellow' is equal to the string '" + value + "'.");
}
}
determineOrder("brick");
determineOrder("yellow");
determineOrder("zoo");
7.HTML方法
Map&Set
Set内部判断两个值是否相同使用的算法为“Same-value equality”,它类似于精确相等运算符(===),主要的区别是NaN等于自身,而精确相等运算符认为NaN不等于自身。
Set方法 | 描述 |
Set() | 构造函数,可以接受一个数组,或者具有iterable接口的其他数据结构作为参数 |
add(value) | 添加某个值,返回Set结构本身 |
delete(value) | 删除某个值,返回一个布尔值,表示删除是否成功 |
has(value) | 返回一个布尔值,表示参数是否为Set的成员 |
clear() | 清除所有成员,没有返回值 |
keys() | 返回键名的遍历器 用法:for(let item of set.values()) |
values() | 返回键值的遍历器 |
entries() | 返回键值对的遍历器 |
forEach() | 使用回调函数遍历每个成员 |
Map方法 | 描述 |
Map() | 构造函数 |
set(key,value) | 设置key所对应的键值,然后返回整个Map结构。如果key已经有值,则键值被更新,否则新生成该键 |
get(key) | 读取key对应的键值,若未找到key则返回undefined |
has(key) | 返回一个布尔值,表示某个键是否存在于Map结构中 |
delete(key) | 删除某个键,返回true;删除失败返回false |
clear() | 清除所有成员,没有返回值 |
keys() | 返回键名的遍历器 用法:for(let item of map.values()) |
values() | 返回键值的遍历器 |
entries() | 返回键值对的遍历器 |
forEach() | 使用回调函数遍历每个成员 用法:map.forEach(function(value, key, map){ }) |
WeakSet与Set的区别:
①WeakSet成员只能是对象,而不能是其他类型的值
②WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象是否还存在于WeakSet中。
③WeakSet不可遍历
实例
1.去除数组的重复元素
function dedupe(array){
return Array.from(new Set(array));
}
console.log(dedupe([1, 1, 2, 3])); // [1, 2, 3]
2.扩展运算符(...)内部使用for...of循环,所以也可以用于Set结构
扩展运算符和Set结构相结合也可以去除数组的重复成员
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)];
console.log(unique); // [3, 5, 2]
3.利用Set实现并集(Union)、交集(Intersect)、差集(Difference)
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
console.log(union); // Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
console.log(intersect); // Set {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
console.log(difference); // Set {1}