In-depth Understanding of ES6 007 [Study Notes]

Set and Map Collections. In JS, there is an `in` operator that can determine if a property exists in an object without needing to read the object's value, returning true if it exists. However, the `in` operator also checks the object's prototype chain, so using this method is only relatively safe when the object's prototype is null. Set Collection: `let set = new Set()` `set.add(5)` `set.add("5")` `console.log(s…`

Set Collection and Map Collection

In JS, there is an in operator, which can determine if a property exists in an object without needing to read the object's value; if it exists, it returns true. However, the `in` operator also checks the object's prototype, so this method is only reliable when the object's prototype is null.

Set Collection

let set = new Set()
set.add(5)
set.add("5")
console.log(set.size) // 2
const key1={},key2={}
set.add(key1)
set.add(key1)
console.log(set.size) // 4
// 传入相同值实际上会被忽略
let set1 = new Set(1,2,3,4,5,5,5,5)
console.log(set.size) //5
set1.has(5) //true
set1.has(6) // false
set1.delete(5)
set1.has(5) //false

set1.clear() // 所有元素被清除

A Set collection does not perform forced type conversion on stored values; the number 5 and the string "5" can exist as two independent elements (the engine uses `Object.is()` as mentioned before for judgment). If multiple objects are added to a Set, they remain independent of each other.

Set Collection's forEach Method

The callback function of the forEach() method accepts the following 3 parameters

  • The next index position in the Set collection
  • A value identical to the first parameter
  • The Set collection being iterated over itself

The `forEach()` method of a Set collection has a peculiar difference from the `forEach()` method in arrays: the values of the first two parameters of the callback function are actually the same. In fact, the `forEach()` callback function of a Map collection also accepts 3 parameters, where the first two are the value and the key, respectively.

The second parameter of the `forEach` function is the same as for arrays; if `this` needs to be used within the callback function, it can be passed as the second argument.

let set = new Set([1,2])
let processor = {
  output(value){
    console.log(value)
  },
  process(dataSet){
    // 这里使用箭头函数,就无须再将this作为第二个参数传入回调函数了
    dataSet.forEach(function(value){
      this.output(value)
    },this)
  }
}
processor.process(set)

Although Set collections are more suitable for tracking multiple values and each element in the collection can be manipulated using the `forEach()` method, you cannot access elements in a collection directly by index like you would with array elements. If necessary, it's best to convert the Set collection into an array first.

let set = new Set([1,2,3,3,3,4,5])
arrray = [...set]
console.log(array) // [1,2,3,4,5] 去重

function eliminateDuplicates(items){
  return [...new Set(items)]
}
let numbers = [1,2,3,3,3,4,5],
noDuplicates = eliminateDuplicates(numbers);
console.log(noDuplicates); // [1,2,3,4,5]

Weak Set Collection

Storing an object in a Set instance is similar to storing it in a variable: as long as a reference exists in the Set instance, the garbage collector cannot free the object's memory space. Thus, the Set type mentioned earlier can be considered a Set collection with strong references. As follows:

let set = new Set(),
key = {};
set.add(key);
console.log(set.size) // 1
// 移除原始引用
key = null;
console.log(set.size) // 1
// 重新取回原始引用
key = [...set][0]

For example, if we use this Set to store a DOM object, and a script removes this DOM element, the Set will still retain this reference (causing a memory leak). Therefore, ES6 introduced the WeakSet collection. A WeakSet can only store weak references to objects and cannot store primitive values; if a weak reference in the collection is the object's only reference, it will be garbage collected and its memory released.

// 集合支持add()/has()/delete()
let set = new WeakSet(),key = {};
// 向集合添加对象
set.add(key);
console.log(set.has(key)); // true
set.delete(key);
console.log(set.has(key)); // false
let key1 = {}, key2 = {};
set = new WeakSet([key1,key2]) // 如果数组中包含其非对象值,程序会抛出错误
console.log(set.has(key1)) // true
console.log(set.has(key2)) // true

// #################
// 移除对象key的最后一个强引用(Weak Set中的引用也自动移除)
let set = new Set(),
key = {};
set.add(key);
console.log(set.has(key)) // true
// 移除对象key的最后个强引用(Weak Set中的引用也自动移除)
key = null;
// 这段代码执行过后,就无法访问WeakSet中的key的引用了,由于我们需要向has方法传递一个强引用才能验证这个弱引用是否已被移除了。
  • WeakSet
  • Passing non-object arguments to the add/has/delete methods will cause the program to throw an error.
  • Not iterable; cannot use `for-of` loops.
  • Does not expose any iterators (`keys` and `values`), so its contents cannot be inspected by the program itself.
  • Does not support `forEach`.
  • Does not support `size`.

Map

  • set
  • get
  • has
  • delete
  • clear
  • size property

Initialization Method

let map = new Map([["name","Nicholas"],["age",23]])

forEach((value,key,ownerMap)=>{}, binding context)

let map = new Map([["name","Nicholas"],["age",23]])
map.forEach(function(value,key,ownerMap){
   console.log(key+" "+value);
   console.log(ownerMap === map)
})

WeakMap

The principle is consistent with WeakSet: keys are weak references to objects, and keys can only store objects.

let map = new WeakMap(),
element = document.querySelector('.element');
map.set(element,"Original")
let value = map.get(element)
console.log(value) // Original
// 移除element元素
element.parentNode.removeChild(element);
element = null;
// 此时Weak Map集合为空

Private Object Data

function Person(name){
  this._name = name;
}
Person.prototype.getName = function(){
  return this._name;
}
// 约定前缀为下划线的属性为私有属性,不允许在对象实例外改变这个属性。例如,只能通过getName()方法读取this._name,所以它也有可能在无意间被覆写

ES5 can create an object with nearly true private data using the following pattern:

var Person = (function(){
  var privateData = {},
  privateId = 0;
  function Person(name){
    Object.defineProperty(this,"_id",{value:privateId++})
    privateData[this._id] = {
      name:name
    }
  }
  Person.prototype.getName = function(){
    return privateData[this._id].name
  }
  return Person
}())

When the `Person` constructor is called, the value of the `_id` property is incremented by 1. This property is non-enumerable, non-configurable, and non-writable. The biggest problem with the above code is the inability to actively manage it; since it's impossible to know when an object instance is destroyed, the data in `privateData` will never disappear. However, using a WeakMap collection can solve this problem.

let Person = (function(){
  let privateData = new WeakMap();
  function Person(name){
    privateData.set(this,{name:name})
  }
  Person.prototype.getName = function(){
    return privateData.get(this).name
  }
  return Person
}())
// 只要对象实例被销毁,相关信息也会被销毁,从而保证了信息的私有性

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4333

(0)
Walker的头像Walker
上一篇 Mar 10, 2026 00:00
下一篇 Mar 8, 2026 15:40

Related Posts

  • Go Engineer Comprehensive Course: protoc-gen-validate Study Notes

    protoc-gen-validate: Introduction and Usage Guide ✅ What is protoc-gen-validate? protoc-gen-validate (PGV for short) is a Protocol Buffers plugin used to add validation logic for struct fields in generated Go code. It automatically generates validation code for each field by adding validation rules in .proto files, saving you the trouble of manually...

    Personal Nov 25, 2025
    1.4K00
  • In-depth Understanding of ES6 003 [Study Notes]

    Function parameter default values, as well as some details about the `arguments` object, how to use expressions as parameters, and the temporal dead zone for parameters. Previously, setting default values always relied on expressions containing the logical OR operator. When the preceding value was false, the latter value would always be returned. However, this became problematic if we passed 0 as an argument, requiring type verification. For example, `function makeRequest(url,timeout,callback){ timeout = t...`

    Personal Mar 8, 2025
    1.3K00
  • Go Engineering Systematic Course 003 [Study Notes]

    grpc grpc grpc-go grpc seamlessly integrates protobuf protobuf. For those of you accustomed to using JSON and XML data storage formats, I believe most have never heard of Protocol Buffer. Protocol Buffer is actually a lightweight & efficient structured data storage format developed by Google, and its performance is truly much, much stronger than JSON and XML! protobuf…

    Personal Nov 25, 2025
    25300
  • Go Engineering Systematic Course 014 [Study Notes]

    RocketMQ Quick Start. Go to our various configurations (podman) to see how it's installed. Introduction to Concepts: RocketMQ is a distributed messaging middleware open-sourced by Alibaba and an Apache top-level project. Core components: NameServer: Service discovery and routing; Broker: Message storage, delivery, and fetching; Producer: Message producer (sends messages); Consumer: Message consumer (subscribes to and consumes messages); Topic/Tag: Topic/...

    Personal Nov 25, 2025
    24300
  • Node: Demystified (Shengsi Garden Education) 001 [Learning Notes]

    Node.js: Understanding it from an Asynchronous Programming Paradigm
    Node.js's Positioning and Core Philosophy
    Based on the V8 engine + libuv event-driven library, it brings JavaScript from the browser to the server side. It uses a single-threaded event loop to handle I/O, maximizing CPU time slices while waiting for I/O, making it particularly suitable for high-concurrency, I/O-intensive scenarios. "Don't block the main thread" is its design philosophy: try to offload time-consuming operations to the kernel or a thread pool, and callback results...

    Personal Nov 24, 2025
    34300
EN
简体中文 繁體中文 English