Set、Map、WeakMap以及正则表达式

264 阅读5分钟

Symbol

  • JS的内置原始类型
  • 每个Symbol都不相同 即使它们的值一样
  • 可以放在对象属性里,作为对象属性的类型(对象属性只有String和Symbol两种类型

当其它类型的值被赋值为对象的属性,会被强制转换为String,如

        let obj = {1:2}
        let obj1 = {1:3}
				let arr = [7,5]
				obj[arr] = 111
				obj[obj1] = '哈哈'
        console.log(obj);						//打印出{1: 2, "7,5": 111, "[object Object]": "哈哈", Symbol("foo"): "hello"} 

如上,所有Object被赋值为其它Objcet的属性,都会被强制转换为同一个值(即"[object Object]"),因此重复赋值可能会被顶替,为了避免这种情况,可以使用Symbol作为对象属性的赋值

Set

  • Set对象是值的集合,可以按照插入的顺序迭代它的元素,Set中的元素是唯一的。
  • Set是可迭代对象,可通过 for of 遍历
let ste = new Set('hello world')
console.log(ste);							//因为Set里的元素是唯一的,重复的字母不会出现,因此打印出 [ "h", "e", "l", "o", " ", "w", "r", "d" ]

利用Set中元素唯一的特性实现数组去重:

        let arr = [3, 3, 1, 5, 4, 'red', 11, 11]
        let set = new Set(arr)
        let arr2 = [...set]

Map

  • Map对象是键值对的集合。Map 中的一个键只能出现一次。任何值都可以作为键和值
        let arr = [3, 3, 1, 5, 4, 'red', 11, 11]
				map.set(0,1)
        map.set('ste','你好')
        console.log(map.get(0));					//打印出map属性0对应的值
        map.set(arr,2)
        console.log(map);									//打印出下面

WeakMap

  • WeakMap 对象是一组键/值对的集合,其中的键是弱引用。其键必须是对象,而值可以是任意的。用法和Map基本一致,只不过WeakMap是不可遍历的。
  • 如果key 是引用类型,推荐使用WeakMap

正则表达式

  • 把符合某种规则的字串拿出来
  • 判断字符串是否符合某种规则
  • 按某种规则分割字符串
  • 替换符合某种规则的子串

如何创建?

  1. 通过字面量的方式来创建—通过特殊符号创建如:

let arr = [] //通过字面量创建空数组

  • let reg = /表达式内容/g 通过字面量创建正则表达式
  1. 通过构造函数方式创建—
let name = 'baidu'
let reg = new RegExp('www.'+name+'.com', 'g'

两种方式后面的字母代表

  • g:global,全文搜索,不添加的话搜索到第一个结果停止搜索
  • i:ingore case,忽略大小写,默认大小写敏感
  • m:multiple lines,多行搜索

如何使用

  1. 调用正则对象本身的函数,如
        let reg = /www.baidu.com/
        console.log(reg.test('www.baidu.comabcsd'))			//test里是否包含了reg,包含,输出true
  1. 在字符串上用
        let step = 'hi1 stephen, hi2 gorge'
        step.search(/1/g)						//全局搜索字符串里第一个1的位置,返回下标
        step.match(/hi/g)						//匹配hi,返回一个数组,里面装满match到的hi
        step.replace(/hi/g, '你好')	//把全部hi替换为你好
        step.split(/hi/g)						//返回一个数组,把原字符串按hi的位置进行切割

一个在正则上用,传递的是字符串;一个在字符串用,传递的是正则

正则单字符匹配

在正则表达式中,用[内容]表示符合内容的单字符,如

        let reg = /[1-9]/
        console.log(reg.test('12345679'))				//匹配字符串中有无一个处于1-9的数字

        let reg1 = /#[0-9a-f][0-9a-f][0-9a-f]/	//匹配#(0-9之间的数字或a-f之间的字母)*3
        console.log(reg1.test('#123'));
        console.log(reg1.test('3afd'));

        let reg2 = /[Ss]tep/										//匹配(大小S)tep
        console.log(reg2.test('hi,stephen'));
        console.log(reg2.test('hi,Stephen'));

        let reg3 = /[hello]/									//匹配[hello],特殊符号前加\对其进行转义
        console.log(reg3.test('[hello] stephen'));

预定义匹配

  • . 匹配一个除回车和换行外的任意字符
  • \d 匹配一个数字字符
  • \D 匹配一个非数字字符
  • \s 匹配一个空白字符
  • \S 匹配一个非空白字符
  • \w 匹配一个字母、数字、下划线
  • \W 匹配一个非单词字符

匹配字符位数

  • ? 前面的(单个)字符出现0次或1次(可有可无)
    • 前面的字符出现1次或多次
    • 前面的字符出现0次或多次
  • {n} 前面的字符出现n次
  • {n,m} 前面的字符出现 n 到 m 次
  • {n,} 前面的字符至少出现 n 次

let num = /\d{11}/ 匹配十一位数字

边界

  • /^xyz/ 匹配以 xyz 开头的字符串
  • /abc$/ 匹配以 abc 结尾的字符串
let reg = /^hi/	//匹配以hi开头
reg.test('hello hi')				//false
  • /\bhi\b/ 匹配是单词的hi(左右两侧以字符串开头、结尾、中横线、空格)
  • /\Babc\B 匹配不是单词的abc

应用:判断手机号

let reg11 = /^1\d{10}$/ 以1开头,以数字结尾

贪婪模式与非贪婪模式

'123456789'.match(/\d{3,5}/g 会匹配几个

默认情况下是贪婪模式,会尽可能多地作匹配,因此结果会是[ "12345", "6789" ]

在量词后加 ? 开启非贪婪模式,尽可能少地匹配

'123456789'.match(/\d{3,5}?/g //结果为[ "123", "456", "789" ]

分组—用于把匹配的部分拿出

let str = '图片尺寸为1440x980px' 现在遇到这样一串字符,怎样分别拿出长和宽

str.match(/\d+x\d+/) 只能匹配到1440x980

在两个\d+加上(),就可以

str.match(/(\d+)x(\d+)/ 就不但可以匹配到1440x980,还把两个数字单独列出,结果为[ "1440x980", "1440", "980" ]

如果str再高级一点

let str = '图片1尺寸为1440x980, 图片2尺寸为360x280, 图片3尺寸为980x670'

那就

str2 = [...str.matchAll(/(\d+)x(\d+)/g)] //把str中所有符合条件的找出来

因为matchAll出来的结果是一个可迭代对象,所以可用 ... 把它变为数组,结果为:

0: Array(3)[ "1440x980", "1440", "980" ]

1: Array(3)[ "360x280", "360", "280" ]

2: Array(3)[ "980x670", "980", "670" ]