首页 > 编程语言 >你不知道的javascript-14(Symbol,map,set)

你不知道的javascript-14(Symbol,map,set)

时间:2025-01-18 16:03:00浏览次数:3  
标签:map set const 14 对象 Symbol Set console log

1.Symbol(生成唯一标识符)

Symbol 是 JavaScript 中的一种基本数据类型,它表示唯一的、不可变的值。以下是关于 Symbol 的详细说明

const sym1 = Symbol();
const sym2 = Symbol("description");
    • 使用 Symbol() 函数可以创建一个新的 Symbol。
    • 每个 Symbol 都是唯一的,即使它们的描述相同。
  • 唯一性
const key1 = Symbol("key");
const key2 = Symbol("key");
console.log(key1 === key2); // false
    • Symbol 的主要特性是其唯一性,这使得它非常适合用作对象属性的键,以避免命名冲突。
  • 可选描述
const sym = Symbol("This is a description");
console.log(sym.toString()); // Symbol(This is a description)
    • 创建 Symbol 时可以传递一个字符串作为描述,但这仅用于调试(如在控制台输出),并不影响 Symbol 的唯一性。
  • 作为对象属性
const obj = {};
const uniqueKey = Symbol("unique");
obj[uniqueKey] = "value";
console.log(obj[uniqueKey]); // value
    • 使用 Symbol 作为对象属性的键,可以确保该属性不会与其他属性发生冲突。
  • 全局 Symbol 注册表
const sym3 = Symbol.for("sharedKey");
const sym4 = Symbol.for("sharedKey");
console.log(sym3 === sym4); // true
console.log(Symbol.keyFor(sym3)); // sharedKey
    • 如果需要在不同的上下文中共享同一个 Symbol,可以使用全局 Symbol 注册表。
    • 使用 Symbol.for() 方法可以根据给定的键从全局注册表中获取 Symbol,如果不存在则创建并注册。
    • 使用 Symbol.keyFor() 方法可以根据 Symbol 获取其在全局注册表中的键。
  • 内置的 Symbol
const myIterable = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next: () => ({ value: i++, done: i > 2 })
    };
  }
};
for (let value of myIterable) {
  console.log(value);
}
// 输出:
// 0
// 1
// 2
    • JavaScript 提供了一些内置的 Symbol,用于定义语言内部的行为。
    • 例如:Symbol.iterator 用于自定义对象的迭代行为。

在Symbol出现之前对象的键本质上就是一个字符串

Symbol作为对象属性的键,而这些属性是独一无二的,可以防止属性名的冲突

2.set(数组的拓展)

Set 是 JavaScript 中的一种集合数据结构,它存储唯一的值,无论是原始值还是对象引用。以下是关于 Set 的详细说明:

创建和初始化 Set

  • 创建一个空的 Set
const mySet = new Set();
  • 使用数组初始化 Set
const mySet = new Set([1, 2, 3, 4, 5]);
console.log(mySet); // Set(5) { 1, 2, 3, 4, 5 }

基本操作

  • 添加元素
mySet.add(6);
console.log(mySet); // Set(6) { 1, 2, 3, 4, 5, 6 }
    • 使用 add() 方法向 Set 中添加元素。
  • 删除元素
mySet.delete(3);
console.log(mySet); // Set(5) { 1, 2, 4, 5, 6 }
    • 使用 delete() 方法从 Set 中删除指定元素。
  • 检查元素是否存在
console.log(mySet.has(2)); // true
console.log(mySet.has(3)); // false
    • 使用 has() 方法检查 Set 中是否包含某个元素。
  • 清空 Set
mySet.clear();
console.log(mySet); // Set(0) {}
    • 使用 clear() 方法清空 Set 中的所有元素。

遍历 Set

  • 使用 for...of 循环
const mySet = new Set([1, 2, 3]);
for (let item of mySet) {
  console.log(item);
}
// 输出:
// 1
// 2
// 3
  • 使用 forEach 方法
mySet.forEach((value) => {
  console.log(value);
});
// 输出:
// 1
// 2
// 3
  • 转换为数组
const mySet = new Set([1, 2, 3]);
const arr = [...mySet];
console.log(arr); // [1, 2, 3]

const arr2 = Array.from(mySet);
console.log(arr2); // [1, 2, 3]
    • 使用扩展运算符或 Array.from() 方法将 Set 转换为数组。

Set 的特性

  • 唯一性
const mySet = new Set([1, 1, 2, 2, 3, 3]);
console.log(mySet); // Set(3) { 1, 2, 3 }
    • Set 中的每个值都是唯一的,重复添加相同的值不会生效。
  • 大小
console.log(mySet.size); // 3
    • 使用 size 属性获取 Set 中元素的数量。

Set 和其他数据结构的结合

  • 与数组结合
const array = [1, 2, 2, 3, 4, 4, 5];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4, 5]
    • 可以使用 Set 来去重数组中的元素。
  • 与 Map 结合
const myMap = new Map();
const setKey = new Set([1, 2, 3]);
myMap.set(setKey, "value");
console.log(myMap.get(setKey)); // "value"
    • Set 可以作为 Map 的键。

性能优势

  • 查找、插入和删除操作的时间复杂度为 O(1)
    • 这使得 Set 在处理大量数据时非常高效。

通过这些特性和方法,Set 提供了一种简洁且高效的解决方案来处理唯一值的集合。它在去重、查找和遍历等场景中非常有用。

3.weakSet(弱引用的set)

1.应用

主要特点:

  1. 弱引用:WeakSet 中的对象引用是弱引用,这意味着这些对象不会阻止垃圾回收器回收它们。
  2. 不可迭代:WeakSet 不可迭代,因此不能使用 for...of 循环或 Array.from() 方法来遍历其内容。
  3. 仅存储对象:WeakSet 只能存储对象,不能存储原始值(如字符串、数字等)。
  4. 有限的方法:WeakSet 提供的方法非常有限,主要包括 adddeletehas

常用方法:

  • add(value):向 WeakSet 中添加一个对象。
  • delete(value):从 WeakSet 中删除一个对象。
  • has(value):检查 WeakSet 中是否存在某个对象。
// 创建一个新的 WeakSet
const weakSet = new WeakSet();

// 创建一些对象
const obj1 = {};
const obj2 = {};
const obj3 = {};

// 向 WeakSet 中添加对象
weakSet.add(obj1);
weakSet.add(obj2);

// 检查对象是否在 WeakSet 中
console.log(weakSet.has(obj1)); // true
console.log(weakSet.has(obj3)); // false

// 删除对象
weakSet.delete(obj1);
console.log(weakSet.has(obj1)); // false

// 尝试添加非对象
try {
  weakSet.add(123); // 抛出 TypeError
} catch (e) {
  console.error(e.message); // "Invalid value used in weak set"
}

使用场景:

  1. 缓存:当你需要缓存对象但不希望这些对象阻止垃圾回收时,可以使用 WeakSet
  2. 私有属性:在某些情况下,可以使用 WeakSet 来存储对象的私有属性。
  3. 标记对象:当你需要标记一组对象但不希望这些标记影响对象的生命周期时,可以使用 WeakSet

Set 的比较:

  • Set
    • 存储任意类型的值(对象或原始值)。
    • 强引用,存储的对象不会被垃圾回收。
    • 可迭代,可以使用 for...of 循环或 Array.from() 方法。
    • 提供更多的方法,如 sizeclear 等。
  • WeakSet
    • 仅存储对象。
    • 弱引用,存储的对象可以被垃圾回收。
    • 不可迭代。
    • 提供有限的方法,如 adddeletehas

2.强引用与弱引用

强引用(Strong Reference)

定义:

强引用是指某个对象被其他对象或变量直接引用,只要这些引用存在,垃圾回收器就不会回收该对象的内存。

特点:
  • 持久性:只要存在强引用,对象就不会被垃圾回收。
  • 内存占用:强引用可能导致内存泄漏,因为即使对象不再需要,只要强引用存在,内存不会被释放。

弱引用(Weak Reference)

定义:

弱引用是指某个对象被其他对象或变量引用,但这种引用不会阻止垃圾回收器回收该对象的内存。当没有任何强引用指向该对象时,垃圾回收器可以回收该对象。

特点:
  • 临时性:对象只有在没有任何强引用时才会被垃圾回收。
  • 内存管理:弱引用有助于避免内存泄漏,因为对象可以被自动回收。
  • 不可迭代:WeakSetWeakMap 是 JavaScript 中实现弱引用的主要方式,但它们不可迭代

4.map(对象的拓展)

1.简介

以前的对象的键只能使用字符串或者Symbol,而使用 map之后键可以是任何的数据类型

主要特点

  1. 键值对存储:
    • Map 存储键值对,键和值可以是任何类型。
    • 键的类型不受限制,可以是对象、函数、基本类型(如字符串、数字、布尔值等)。
  1. 保持插入顺序:
    • Map 按照键值对插入的顺序进行迭代。
  1. 动态大小:
    • Map 的大小是动态的,可以通过 size 属性获取当前键值对的数量。
  1. 内置方法:
    • 提供多种方法来操作和查询键值对,如 setgethasdeleteclear 等。
  1. 迭代器:
    • Map 可以通过迭代器进行遍历,支持 for...of 循环和 entrieskeysvalues 方法。

2.用法

// 创建一个新的 Map
const myMap = new Map([
  ['name', 'Alice'],
  ['age', 25],
  [true, 'isAdult']
]);

// 添加新的键值对
myMap.set('city', 'Wonderland');

// 获取值
console.log(myMap.get('name')); // "Alice"
console.log(myMap.get('age')); // 25
console.log(myMap.get(true)); // "isAdult"
console.log(myMap.get('city')); // "Wonderland"

// 检查键是否存在
console.log(myMap.has('name')); // true
console.log(myMap.has('gender')); // false

// 删除键值对
console.log(myMap.delete('age')); // true
console.log(myMap.has('age')); // false

// 获取 Map 的大小
console.log(myMap.size); // 3

// 遍历 Map
for (const [key, value] of myMap) {
  console.log(key, value);
}
// 输出:
// name Alice
// true isAdult
// city Wonderland

// 使用 entries() 方法
for (const [key, value] of myMap.entries()) {
  console.log(key, value);
}

// 使用 keys() 方法
for (const key of myMap.keys()) {
  console.log(key);
}

// 使用 values() 方法
for (const value of myMap.values()) {
  console.log(value);
}

3.应用场景

  1. 缓存:
  • 使用 Map 实现缓存机制,键可以是复杂的对象。
const cache = new Map();

function fetchData(url) {
  if (cache.has(url)) {
    return cache.get(url);
  }
  // 模拟异步请求
  const data = { url, content: "Data from " + url };
  cache.set(url, data);
  return data;
}

console.log(fetchData('https://api.example.com/data1'));
console.log(fetchData('https://api.example.com/data1')); // 从缓存中获取
  1. 计数器:
  • 使用 Map 统计元素出现的次数。
const words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const wordCount = new Map();

words.forEach(word => {
  wordCount.set(word, (wordCount.get(word) || 0) + 1);
});

console.log(wordCount); // Map { 'apple' => 3, 'banana' => 2, 'orange' => 1 }
  1. 关联数据:
    • 使用 Map 关联不同类型的键和值。
const userSettings = new Map();
const user1 = { id: 1, name: 'Alice' };
const user2 = { id: 2, name: 'Bob' };

userSettings.set(user1, { theme: 'dark', language: 'en' });
userSettings.set(user2, { theme: 'light', language: 'es' });

console.log(userSettings.get(user1)); // { theme: 'dark', language: 'en' }
console.log(userSettings.get(user2)); // { theme: 'light', language: 'es' }

5.weakmap

1.介绍

  1. 键必须是对象:
  • WeakMap 的键必须是对象或 null。尝试使用其他类型的值(如字符串、数字、布尔值等)作为键会抛出 TypeError
  1. 弱引用:
  • WeakMap 中的键是弱引用,这意味着如果键对象在 WeakMap 中是唯一的引用,垃圾回收器可以回收这些对象。
  • 这有助于避免内存泄漏,因为对象可以被自动回收。
  1. 不可迭代:
  • WeakMap 不可迭代,因此不能使用 for...of 循环或 Array.from() 方法来遍历其内容。
  • 无法获取 WeakMap 中的所有键或值。
  1. 有限的方法:
  • WeakMap 提供的方法非常有限,主要包括 setgethasdelete

2.用法

// 创建一个新的 WeakMap
const weakMap = new WeakMap();

// 创建一些对象
const obj1 = {};
const obj2 = {};
const obj3 = {};

// 向 WeakMap 中添加对象
weakMap.set(obj1, 'value1');
weakMap.set(obj2, 'value2');

// 获取值
console.log(weakMap.get(obj1)); // "value1"
console.log(weakMap.get(obj2)); // "value2"
console.log(weakMap.get(obj3)); // undefined

// 检查键是否存在
console.log(weakMap.has(obj1)); // true
console.log(weakMap.has(obj3)); // false

// 删除对象
weakMap.delete(obj1);
console.log(weakMap.has(obj1)); // false

// 尝试添加非对象
try {
  weakMap.set(123, 'value3'); // 抛出 TypeError
} catch (e) {
  console.error(e.message); // "Invalid value used in weak map"
}

3.主要用途

为什么 WeakMap 有用?

  1. 自动垃圾回收:
  • WeakMap 的键是弱引用,这意味着当键对象不再被其他引用时,垃圾回收器可以回收这些对象及其关联的数据。
  • 这有助于避免内存泄漏,特别是在处理大量对象或 DOM 元素时。
  • 2.封装私有数据:
  • 使用 WeakMap 可以实现真正的私有属性,这些属性不会暴露在对象的公共接口中。
  • 这有助于保持对象的封装性,避免外部代码直接访问和修改私有数据。
  • 3.高效缓存:
  • WeakMap 适用于需要缓存对象数据的场景,特别是当这些对象可能会被频繁创建和销毁时。
  • 通过使用 WeakMap,可以确保缓存数据在对象不再需要时被自动清理。

我只能说看看就好,现在水平完全用不到

标签:map,set,const,14,对象,Symbol,Set,console,log
From: https://blog.csdn.net/weixin_67448099/article/details/145214083

相关文章

  • [ZJOI2014] 力 题解
    容易发现:\[E_i=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^n\frac{q_j}{(i-j)^2}\]不妨设\(a_i=q_i,b_i=\dfrac1{i^2}\):\[E_i=\sum_{j=1}^{i-1}a_jb_{i-j}-\sum_{j=1}^{n-i}a_jb_{j-i}\]发现前半部分就是多项式乘法,后半部分与[BZOJ2194]一致。直接FFT干过去即可......
  • JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请
    目录JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)一、什么时候该使用Array.map(),与forEach()的区别是什么?1、什么时候该用Array.map()2、Array.map()与Array.forEach()的......
  • ADCP414、ADCP416四通道125MSPS速率ADC替代AD9653、AD9253,可提供ZZKK证明
    ADCP416-125/105/80是一款4通道、16位、125/105/80MSPS模数转换器(ADC),内置片内采样保持电路,专门针对低成本、低功耗、小尺寸和易用性而设计。该产品的转换速率最高可达125MSPS,具有杰出的动态性能与低功耗特性,适合比较重视小封装尺寸的应用。ADCP416-125特性和优势--电源供电:1.......
  • C-猪猪养成计划1(set)
    题目链接:https://ac.nowcoder.com/acm/contest/99785/C题意:给定一个数组,操作q次,分别为标记和查询思路:将每一个数组值放入集合set中,消除掉已经遍历过的数组值,通过set二分来加速区间遍历注意:集合本身就存在二分函数lower_bound,通过.lower_bound()调用set的erase操作分为......
  • JAVA安全之JDK8u141版本绕过研究
    基本介绍从JDK8u141开始JEP290中针对RegistryImpl_Skel#dispatch中bind、unbind、rebind操作增加了checkAccess检查,此项检查只允许来源为本地,下面以bind为例:publicvoiddispatch(Remotevar1,RemoteCallvar2,intvar3,longvar4)throwsException{if(var4!=4......
  • 请说明 Vue 3 中的 setup() 函数的作用及其用法
    深入理解Vue3中的setup()函数在Vue3中,性能和可维护性得到了显著提升,其中最引人注目的变化之一就是引入了CompositionAPI,而setup()函数则是这一API的核心部分。本文将深入探讨setup()函数的作用及其用法,帮助您理解如何在Vue3中更高效地组织和管理组件逻......
  • 1998-2014年中国工业用水数据集
    中国工业用水数据集是根据全国各地单独报告的工厂级水资源信息汇编而成的。这种来自微观水平工厂报告的独特DGP的粒状数据不同于所有其他研究甚至官方统计中基于固定部门特定水密度的宏观水平估计。它包含了1,480,265个工厂每年的观察,提供了前所未有的细节和对水使用模式的洞察......
  • 题解:CF140A New Year Table
    CF140ANewYearTable思路注意到题目中提到了大圆与小圆相切,我们可以计算由两条经过小圆周长与大圆圆心的切线组成的圆心角的度数。但是这个角度其实不好算,所以我们可以求出它一半的正弦值,也就是\(b\div(a-b)\),然后用asin函数求出其度数(以弧度为单位)。最后答案就是判断\(......
  • 为什么使用ROS的remap标签不起作用?
    1.remap的作用remap可以让ROS节点订阅发布的topic名字更换为另外一个名字。例如<remapfrom="/old_topic"to="/new_topic"/>“”或者<remapfrom="topic"to="/device1/topic"/>2.问题:为什么使用remap后,topic没有按照预期实现?通过rqt查看,发现两个node之间预期可以展示出......
  • map.merge(num, 1, Integer::sum); 和 map.put(num, map.getOrDefault(num, 0) + 1);
    以下是对map.merge(num,1,Integer::sum);和map.put(num,map.getOrDefault(num,0)+1);的比较:代码示例以下是使用map.merge(num,1,Integer::sum);的示例代码:for(intnum:nums){map.merge(num,1,Integer::sum);}以下是使用ma......