Javascript基础-Set、Map、WeakMap、正则表达式

✊不积跬步,无以至千里;不积小流,无以成江海。

Symbol的使用

Symbol 是 ECMAScript 6 中引入的一种新的原始数据类型,用于表示独一无二的标识符。它的主要特点是创建的每个 Symbol 值都是唯一的,不会与其他 Symbol 值相等。

Symbol 的使用可以有以下几个方面:

  1. 创建 Symbol 值:
ini 复制代码
let sym1 = Symbol();
let sym2 = Symbol("description");

使用 Symbol() 构造函数创建一个新的 Symbol 值,可选参数 "description" 是可选的描述符,用于标识 Symbol 的用途或含义。

  1. 唯一性:
ini 复制代码
let sym1 = Symbol("key");
let sym2 = Symbol("key");
console.log(sym1 === sym2); // 输出: false

每个 Symbol 值都是唯一的,即使它们的描述符相同,它们也不相等。

  1. Symbol 作为对象属性的键:
ini 复制代码
const MY_KEY = Symbol();
let obj = {};

obj[MY_KEY] = "value";
console.log(obj[MY_KEY]); // 输出: "value"

Symbol 值可以作为对象属性的键,用于确保属性的唯一性。

  1. Symbol 值的隐藏属性:
javascript 复制代码
const PASSWORD = Symbol();
class User {
  constructor(name, password) {
    this.name = name;
    this[PASSWORD] = password;
  }

  getPassword() {
    return this[PASSWORD];
  }
}

let user = new User("John", "secret");
console.log(user.name); // 输出: "John"
console.log(user.getPassword()); // 输出: "secret"
console.log(user[PASSWORD]); // 输出: undefined

Symbol 值可以用于定义对象的隐藏属性,这些属性不会被常规方式访问到,但可以通过 Symbol 作为键来访问。

Symbol 的使用可以提供更好的标识符保证,避免属性冲突和重写问题,以及控制对象的隐藏属性。

Set的用法、Set实现数组去重

Set 是 ECMAScript 6 中引入的一种新的数据结构,它允许存储任何类型的唯一值,没有重复的元素。Set 内部的元素是按插入顺序排列的。

Set 的使用有以下几个方面:

  1. 创建 Set:
vbnet 复制代码
let set = new Set();

使用 new Set() 创建一个新的 Set 对象。

  1. 添加元素到 Set:
csharp 复制代码
let set = new Set();
set.add(1);
set.add("apple");
set.add(true);

使用 add 方法向 Set 中添加元素,保证元素的唯一性。

  1. 移除元素:
vbnet 复制代码
let set = new Set([1, 2, 3]);
set.delete(2);

使用 delete 方法从 Set 中移除指定的元素。

  1. 检查元素是否存在:
vbscript 复制代码
let set = new Set([1, 2, 3]);
console.log(set.has(2)); // 输出: true
console.log(set.has(4)); // 输出: false

使用 has 方法检查 Set 中是否存在指定的元素。

  1. 获取 Set 的大小:
arduino 复制代码
let set = new Set([1, 2, 3]);
console.log(set.size); // 输出: 3

使用 size 属性获取 Set 中元素的数量。

  1. 遍历 Set:
javascript 复制代码
let set = new Set([1, 2, 3]);
set.forEach((value) => {
  console.log(value);
});

使用 forEach 方法遍历 Set 中的每个元素。

Set 可以用于实现数组去重,由于 Set 只存储唯一的值,可以很方便地过滤掉数组中的重复元素。例如:

ini 复制代码
let array = [1, 2, 3, 2, 4, 1, 5];
let uniqueArray = [...new Set(array)];
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]

上述代码中,通过将数组转换为 Set,然后使用扩展运算符 ... 将 Set 转换回数组,即可得到去重后的数组。Set 的使用可以提供高效的去重功能,并且具有简单易用的接口。

Map的用法

Map 是 ECMAScript 6 中引入的一种新的数据结构,它是一种键值对的集合,其中每个键都是唯一的。与普通对象相比,Map 提供了更灵活的键类型,并且可以保持插入顺序。

Map 的使用有以下几个方面:

  1. 创建 Map:
ini 复制代码
let map = new Map();

使用 new Map() 创建一个新的 Map 对象。

  1. 添加键值对到 Map:
c 复制代码
let map = new Map();
map.set("key1", "value1");
map.set("key2", "value2");

使用 set 方法向 Map 中添加键值对。

  1. 获取值:
arduino 复制代码
let map = new Map();
map.set("key1", "value1");
console.log(map.get("key1")); // 输出: "value1"
console.log(map.get("key2")); // 输出: undefined

使用 get 方法根据键获取对应的值。

  1. 检查键是否存在:
arduino 复制代码
let map = new Map();
map.set("key1", "value1");
console.log(map.has("key1")); // 输出: true
console.log(map.has("key2")); // 输出: false

使用 has 方法检查 Map 中是否存在指定的键。

  1. 移除键值对:
arduino 复制代码
let map = new Map();
map.set("key1", "value1");
map.delete("key1");
console.log(map.has("key1")); // 输出: false

使用 delete 方法从 Map 中移除指定的键值对。

  1. 获取 Map 的大小:
arduino 复制代码
let map = new Map();
map.set("key1", "value1");
console.log(map.size); // 输出: 1

使用 size 属性获取 Map 中键值对的数量。

  1. 遍历 Map:
c 复制代码
let map = new Map();
map.set("key1", "value1");
map.set("key2", "value2");
map.forEach((value, key) => {
  console.log(key, value);
});

使用 forEach 方法遍历 Map 中的每个键值对。

Map 可以用于存储键值对,并且键可以是任意类型。它提供了一种更灵活的键值对集合,适用于需要快速查找和维护插入顺序的场景。

WeakMap介绍

WeakMap 是 ECMAScript 6 中引入的一种特殊的 Map 实现,它的键必须是对象,并且对键的引用是弱引用。这意味着在没有其他引用存在时,键所对应的键值对将被自动回收,不会造成内存泄漏。

WeakMap 的特点和使用方式如下:

  1. 弱引用键:
    WeakMap 的键必须是对象,且只有对象键的引用是弱引用。这意味着如果键对象没有被其他引用所持有,那么它们将会被垃圾回收,对应的键值对也会被自动移除。
  2. 键值对的添加和获取:
    WeakMap 提供了 set(key, value) 方法用于添加键值对,以及 get(key) 方法用于根据键获取对应的值。
ini 复制代码
let wm = new WeakMap();
let key = {};
let value = "Some value";

wm.set(key, value);
console.log(wm.get(key)); // 输出: "Some value"
  1. 检查键是否存在:
    WeakMap 提供了 has(key) 方法用于检查键是否存在于 WeakMap 中。
ini 复制代码
let wm = new WeakMap();
let key = {};
let value = "Some value";

wm.set(key, value);
console.log(wm.has(key)); // 输出: true
  1. 移除键值对:
    WeakMap 提供了 delete(key) 方法用于移除指定的键值对。
ini 复制代码
let wm = new WeakMap();
let key = {};
let value = "Some value";

wm.set(key, value);
wm.delete(key);
console.log(wm.has(key)); // 输出: false
  1. 弱引用的好处:
    由于键是弱引用的,当键对象没有其他引用时,它们将被自动回收。这样可以避免内存泄漏问题,特别适用于需要与对象关联的附加数据,而不会干扰对象的垃圾回收。
  2. WeakMap 的限制:
    WeakMap 没有提供像 Map 那样的迭代方法和遍历功能,也无法直接获取 WeakMap 的大小。这是因为在垃圾回收过程中,WeakMap 中的键可能被自动移除,因此无法确定准确的大小。

WeakMap 的使用场景主要是在需要与对象关联的附加数据,并且希望在对象被回收时自动移除与之关联的数据的情况下。它在某些特定的应用场景下非常有用,尤其是在处理敏感数据时。

正则表达式作用、创建、用法

正则表达式是一种用于匹配和操作文本的强大工具,它可以用于字符串的搜索、替换、验证等操作。正则表达式由一系列字符和特殊字符组成,表示一种模式,用于描述所需匹配的文本规则。

创建正则表达式有两种方式:

  1. 字面量方式:
ini 复制代码
let regex = /pattern/;

使用正斜杠(/)将模式包围起来,创建一个正则表达式对象。

  1. 构造函数方式:
ini 复制代码
let regex = new RegExp("pattern");

使用 RegExp 构造函数创建一个正则表达式对象。

正则表达式的常见用法:

  1. 匹配:
ini 复制代码
let regex = /apple/;
let str = "I have an apple.";
console.log(regex.test(str)); // 输出: true 
//`regex.test(str)` 语法用于测试字符串 `str` 是否与正则表达式 `regex` 匹配。

使用 test 方法检测字符串是否匹配正则表达式。

  1. 搜索和提取:
ini 复制代码
let regex = /apple/;
let str = "I have an apple and a banana.";
console.log(str.match(regex)); // 输出: ["apple"]

使用 match 方法在字符串中搜索并提取匹配正则表达式的部分。

  1. 替换:
ini 复制代码
let regex = /apple/;
let str = "I have an apple.";
let newStr = str.replace(regex, "orange");
console.log(newStr); // 输出: "I have an orange."

使用 replace 方法将匹配正则表达式的部分替换为指定的字符串。

  1. 分割:
ini 复制代码
let regex = /\s+/;
let str = "Hello     World!";
console.log(str.split(regex)); // 输出: ["Hello", "World!"]

使用 split 方法根据匹配正则表达式的部分将字符串拆分为数组。

  1. 标志(Flags):

    正则表达式可以附加标志来修改匹配的行为,常见的标志包括:

    • i:忽略大小写。
    • g:全局匹配,匹配到所有符合条件的部分。
    • m:多行匹配。
ini 复制代码
let regex = /apple/gi;
let str = "I have an Apple and an apple.";
console.log(str.match(regex)); // 输出: ["Apple", "apple"]

正则表达式提供了强大的文本处理能力,可以根据具体需求构建不同的模式来匹配和操作字符串。

判断输入的是否是有效手机号

要判断输入的手机号是否有效,可以使用正则表达式进行匹配。手机号的有效性规则可以根据具体需求而有所不同,以下是一个常见的手机号有效性的正则表达式示例:

javascript 复制代码
function isValidPhoneNumber(phoneNumber) {
  // 使用正则表达式进行匹配
  let regex = /^1[0-9]{10}$/;
  return regex.test(phoneNumber);
}

上述代码中,正则表达式 /^1[0-9]{10}$/ 用于匹配以数字 1 开头,后面跟着 10 个数字的字符串。^:表示字符串必须以 1 开头。 [0-9]:表示字符串可以包含 0 到 9 的数字。{10}:表示字符串必须包含 10 个数字。

使用示例:

ini 复制代码
let phoneNumber1 = "1234567890";
console.log(isValidPhoneNumber(phoneNumber1)); // 输出: false

let phoneNumber2 = "18012345678";
console.log(isValidPhoneNumber(phoneNumber2)); // 输出: true

在上述示例中,isValidPhoneNumber 函数接受一个字符串参数 phoneNumber,并使用正则表达式进行匹配。如果匹配成功,返回 true,表示手机号有效;否则返回 false,表示手机号无效。

贪婪模式和非贪婪模式

在正则表达式中,贪婪模式(Greedy mode)和非贪婪模式(Non-greedy mode)是用于控制匹配行为的两种模式。

  1. 贪婪模式:

    默认情况下,正则表达式采用贪婪模式,即尽可能匹配更多的字符。它会尽量匹配符合模式的最长字符串。

    例如,考虑以下正则表达式和字符串:

ini 复制代码
let regex = /a.*/;
let str = "abcdefg";

console.log(str.match(regex)); // 输出: ["abcdefg"]

在贪婪模式下,a.* 表达式匹配以字母 "a" 开头,后面跟着任意数量的字符(包括 0 个字符)。因此,它会匹配到整个字符串 "abcdefg"

  1. 非贪婪模式:
    非贪婪模式也称为懒惰模式(Lazy mode)或最小匹配模式(Minimal match mode),它与贪婪模式相反,尽量匹配更少的字符。

在正则表达式中,可以在量词(如 *+?{n} 等)后面加上 ? 来表示非贪婪模式。

例如,将上述例子中的正则表达式改为 /a.*?/

ini 复制代码
let regex = /a.*?/;
let str = "abcdefg";

console.log(str.match(regex)); // 输出: ["a"]

在非贪婪模式下,a.*? 表达式匹配以字母 "a" 开头,后面跟着任意数量的字符,但尽量匹配最少的字符。因此,它只匹配到第一个字符 "a"。

正则分组实例

正则表达式中的分组(Grouping)允许将模式的一部分进行分组,并对该分组进行操作或引用。以下是一些正则分组的实例:

  1. 匹配重复的单词:
    正则表达式可以使用分组来匹配重复的单词。例如,要匹配重复的单词 "hello",可以使用分组和反向引用 \1 来实现。
ini 复制代码
let regex = /(\b\w+\b)\s+\1/;
let str = "hello hello world";

console.log(regex.test(str)); // 输出: true

在上述示例中,(\b\w+\b) 表达式表示一个单词的分组,\b 是单词边界,\w+ 匹配一个或多个单词字符。\s+ 匹配一个或多个空白字符。\1 是反向引用,表示对第一个分组的引用,即重复的单词。

  1. 提取日期中的年、月、日:
    分组可以用于提取日期字符串中的年、月、日等部分。
ini 复制代码
let regex = /(\d{4})-(\d{2})-(\d{2})/;
let str = "2023-10-29";

let match = regex.exec(str);
console.log(match[1]); // 输出: "2023"
console.log(match[2]); // 输出: "10"
console.log(match[3]); // 输出: "29"

在上述示例中,(\d{4}) 表达式表示匹配四个数字的年份,(\d{2}) 表达式表示匹配两个数字的月份和日期。使用 exec 方法执行正则表达式,可以从匹配结果中提取分组的值。

  1. 替换匹配的部分:
    分组可以用于替换匹配的部分。例如,将字符串中的 "last name, first name" 格式转换为 "first name last name" 格式:
ini 复制代码
let regex = /(\w+), (\w+)/;
let str = "Doe, John";

let newStr = str.replace(regex, "$2 $1");
console.log(newStr); // 输出: "John Doe"

在上述示例中,(\w+) 分组分别匹配了姓和名。$2$1 是替换字符串中的引用,表示分组的引用顺序。

相关推荐
软件技术NINI2 分钟前
HTML——基本标签
前端·javascript·html
覆水难收呀29 分钟前
三、(JS)JS中常见的表单事件
开发语言·前端·javascript
WebGIS皮卡茂3 小时前
【数据可视化】Arcgis api4.x 热力图、时间动态热力图、timeSlider时间滑块控件应用 (超详细、附免费教学数据、收藏!)
javascript·vue.js·arcgis·信息可视化
Sca_杰4 小时前
vue2使用npm引入依赖(例如axios),报错Module parse failed: Unexpected token解决方案
前端·javascript·vue
waterHBO4 小时前
js 3个事件监听器 EventListeners
开发语言·javascript·ecmascript
荔枝味-5 小时前
html详细知识
前端·javascript·html
帅过二硕ฅ8 小时前
uniapp点击跳转到对应位置
前端·javascript·uni-app
正小安11 小时前
URL.createObjectURL 与 FileReader:Web 文件处理两大法宝的对比
前端·javascript
A黄俊辉A12 小时前
vue3中把封装svg图标为全局组件
前端·javascript·vue.js
老贾爱编程12 小时前
VUE实现刻度尺进度条
前端·javascript·vue.js