`Set` 对象允许你存储任何类型的唯一值，无论是原始值或者是对象引用。

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

## 语法

    new Set([iterable]);

### 参数

iterable
  如果传递一个可迭代对象，它的所有元素将不重复地被添加到新的 Set中。如果不指定此参数或其值为null，则新的 Set为空。

### 返回值

一个新的`Set`对象。

## 简述

`Set`对象是值的集合，你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次，即 Set 中的元素是唯一的。

### 值的相等

因为 Set 中的值总是唯一的，所以需要判断两个值是否相等。在ECMAScript规范的早期版本中，这不是基于和===操作符中使用的算法相同的算法。具体来说，对于 Set s， +0 （+0 严格相等于-0）和-0是不同的值。然而，在 ECMAScript 2015规范中这点已被更改。有关详细信息，请参阅浏览器兼容性 表中的“value equality for -0 and 0”。

另外，`NaN`和`undefined`都可以被存储在Set 中， `NaN`之间被视为相同的值（尽管 NaN !== NaN）。

## 属性

`Set.length`
  `length`属性的值为0。
`get Set[@@species]`
  构造函数用来创建派生对象.
`Set.prototype`
  表示Set构造器的原型，允许向所有Set对象添加新的属性。

## `Set`实例

所有Set实例继承自 `Set.prototype`。

### 属性

`Set.prototype.constructor`
  返回实例的构造函数。默认情况下是`Set`。
`Set.prototype.size`
  返回`Set`对象的值的个数。

### 方法

`Set.prototype.add(value)`
  在`Set对象尾部添加一个元素。返回该` `Set对象。`
`Set.prototype.clear()`
  移除`Set`对象内的所有元素。
`Set.prototype.delete(value)`
  `移除Set的中与这个值相等的元素，返回Set.prototype.has(value)在这个操作前会返回的值（即如果该元素存在，返回true，否则返回false）。``Set.prototype.has(value)在此后会返回false。`
`Set.prototype.entries()`
  `返回一个新的迭代器对象，该对象包含Set对象中的`按插入顺序排列的`所有元素的值的[value, value]数组。为了使这个方法`和`Map对象保持相似，` 每个值的键和值相等。
`Set.prototype.forEach(callbackFn[, thisArg])`
  按照插入顺序，为Set对象中的每一个值调用一次callBackFn。如果提供了`thisArg参数，回调中的this会是这个参数。`
`Set.prototype.has(value)`
  返回一个布尔值，表示该值在`Set中存在与否。`
`Set.prototype.keys()`
  与`values()``方法相同，返回一个新的迭代器对象，该对象包含Set对象中的`按插入顺序排列的`所有元素的值。`
`Set.prototype.values()`
  `返回一个新的迭代器对象，该对象包含Set对象中的`按插入顺序排列的`所有元素的值。`
`Set.prototype[@@iterator]()`
  `返回一个新的迭代器对象，该对象包含Set对象中的`按插入顺序排列的`所有元素的值。`

## 示例

### 使用`Set`对象

    let mySet = new Set();

    mySet.add(1); // Set(1) {1}
    mySet.add(5); // Set(2) {1, 5}
    mySet.add(5); // Set { 1, 5 }
    mySet.add("some text"); // Set(3) {1, 5, "some text"}
    var o = {a: 1, b: 2};
    mySet.add(o);

    mySet.add({a: 1, b: 2}); // o 指向的是不同的对象，所以没问题

    mySet.has(1); // true
    mySet.has(3); // false
    mySet.has(5);              // true
    mySet.has(Math.sqrt(25));  // true
    mySet.has("Some Text".toLowerCase()); // true
    mySet.has(o); // true

    mySet.size; // 5

    mySet.delete(5);  // true,  从set中移除5
    mySet.has(5);     // false, 5已经被移除

    mySet.size; // 4, 刚刚移除一个值
    console.log(mySet); // Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}}

### 迭代Set

    // 迭代整个set
    // 按顺序输出：1, "some text"
    for (let item of mySet) console.log(item);

    // 按顺序输出：1, "some text"
    for (let item of mySet.keys()) console.log(item);

    // 按顺序输出：1, "some text"
    for (let item of mySet.values()) console.log(item);

    // 按顺序输出：1, "some text"
    //(键与值相等)
    for (let [key, value] of mySet.entries()) console.log(key);

    // 转换Set为Array
    var myArr = Array.from(mySet); // [1, "some text"]

    // 如果在HTML文档中工作，也可以：
    mySet.add(document.body);
    mySet.has(document.querySelector("body")); // true

    // Set 和 Array互换
    mySet2 = new Set([1,2,3,4]);
    mySet2.size; // 4
    [...mySet2]; // [1,2,3,4]

    // intersect can be simulated via
    var intersection = new Set([...set1].filter(x => set2.has(x)));

    // difference can be simulated via
    var difference = new Set([...set1].filter(x => !set2.has(x)));

    // 用forEach迭代
    mySet.forEach(function(value) {
      console.log(value);
    });

    // 1
    // 2
    // 3
    // 4

### 实现基本集合操作

    function isSuperset(set, subset) {
        for (var elem of subset) {
            if (!set.has(elem)) {
                return false;
            }
        }
        return true;
    }

    function union(setA, setB) {
        var _union = new Set(setA);
        for (var elem of setB) {
            _union.add(elem);
        }
        return _union;
    }

    function intersection(setA, setB) {
        var _intersection = new Set();
        for (var elem of setB) {
            if (setA.has(elem)) {
                _intersection.add(elem);
            }
        }
        return _intersection;
    }

    function difference(setA, setB) {
        var _difference = new Set(setA);
        for (var elem of setB) {
            _difference.delete(elem);
        }
        return _difference;
    }

    //Examples
    var setA = new Set([1, 2, 3, 4]),
        setB = new Set([2, 3]),
        setC = new Set([3, 4, 5, 6]);

    isSuperset(setA, setB); // => true
    union(setA, setC); // => Set [1, 2, 3, 4, 5, 6]
    intersection(setA, setC); // => Set [3, 4]
    difference(setA, setC); // => Set [1, 2]

### `Array` 相关

    var myArray = ["value1", "value2", "value3"];

    // 用Set构造器将Array转换为Set
    var mySet = new Set(myArray);

    mySet.has("value1"); // returns true

    // 用...(展开操作符)操作符将Set转换为Array
    console.log([...mySet]); // 与myArray完全一致

### `String` 相关

    var text = 'Indiana';

    var mySet = new Set(text);  // Set {'I', 'n', 'd', 'i', 'a'}
    mySet.size;  // 5

### 数组去重

    // Use to remove duplicate elements from the array
    const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
    console.log([...new Set(numbers)])
    // [2, 3, 4, 5, 6, 7, 32]

## 规范

规范 | 状态 | 备注
--- | --- | ---
ECMAScript 2015 (6th Edition, ECMA-262) Set | Standard | 初始定义
ECMAScript Latest Draft (ECMA-262) Set | Draft |

## 浏览器兼容

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
`Set` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`new Set(iterable)` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE No support No | Opera Full support 25 | Safari Full support 9 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`new Set(null)` | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 37 | IE Full support 11 | Opera Full support Yes | Safari Full support 9 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support 12 | Firefox Android Full support 37 | Opera Android Full support Yes | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`Set()` without `new` throws | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 42 | IE Full support 11 | Opera Full support Yes | Safari Full support 9 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support 12 | Firefox Android Full support 42 | Opera Android Full support Yes | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
Key equality for -0 and 0 | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 29 | IE No support No | Opera Full support 25 | Safari Full support 9 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 29 | Opera Android Full support 25 | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 4.0.0
`add` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE Partial support 11 Notes Partial support 11 Notes Notes Returns 'undefined' instead of the 'Set' object. | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support Yes
`clear` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 19 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 19 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`delete` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`entries` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 24 | IE No support No | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 24 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`forEach` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 25 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 25 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`has` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support Yes
`prototype` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 13 | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 14 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support Yes
`size` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 19 Notes Full support 19 Notes Notes From Firefox 13 to Firefox 18, the `size` property was implemented as a `Set.prototype.size()` method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification. | IE Full support 11 | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 19 Notes Full support 19 Notes Notes From Firefox 13 to Firefox 18, the `size` property was implemented as a `Set.prototype.size()` method, this has been changed to a property in later versions conform to the ECMAScript 2015 specification. | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`values` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 24 | IE No support No | Opera Full support 25 | Safari Full support 8 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 24 | Opera Android Full support 25 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`@@iterator` | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 36 Full support 36 No support 27 — 36 Notes Alternate Name Notes A placeholder property named `@@iterator` is used. Alternate Name Uses the non-standard name: `@@iterator` No support 17 — 27 Notes Alternate Name Notes A placeholder property named `iterator` is used. Alternate Name Uses the non-standard name: `iterator` | IE No support No | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 36 Full support 36 No support 27 — 36 Notes Alternate Name Notes A placeholder property named `@@iterator` is used. Alternate Name Uses the non-standard name: `@@iterator` No support 17 — 27 Notes Alternate Name Notes A placeholder property named `iterator` is used. Alternate Name Uses the non-standard name: `iterator` | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`@@species` | Chrome Full support 51 | Edge Full support 13 | Firefox Full support 41 | IE No support No | Opera Full support 38 | Safari Full support 10 | WebView Android Full support 51 | Chrome Android Full support 51 | Edge Mobile Full support 13 | Firefox Android Full support 41 | Opera Android Full support 41 | Safari iOS Full support 10 | Samsung Internet Android Full support 5.0 | nodejs Full support 6.5.0 Full support 6.5.0 Full support 6.0.0 Disabled Disabled From version 6.0.0: this feature is behind the `--harmony` runtime flag.

### Legend

Full support
  Full support
Partial support
  Partial support
No support
  No support
See implementation notes.
  See implementation notes.
User must explicitly enable this feature.
  User must explicitly enable this feature.
Uses a non-standard name.
  Uses a non-standard name.

## 参见

- `Map`
- `WeakMap`
- `WeakSet`