JavaScript学习笔记四

本文详细介绍了JavaScript中的正则表达式,包括创建、测试正则表达式的方法,以及边界符、字符类、量词符等概念。同时,讲解了表单验证中的应用,如用户名、手机号和QQ号的验证规则。还涉及let、const变量声明,函数参数默认值,箭头函数,以及字符串和数组的扩展操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式:

正则表达式概述:

什么是正则表达式:

正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。

正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。

其他语言也会使用正则表达式,本阶段我们主要是利用JavaScript 正则表达式完成表单验证。

正则表达式的特点:
  • 灵活性、逻辑性和功能性非常的强。
  • 可以迅速地用极简单的方式达到字符串的复杂控制。
  • 对于刚接触的人来说,比较晦涩难懂。比如:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$
  • 实际开发,一般都是直接复制写好的正则表达式. 但是要求会使用正则表达式并且根据实际情况修改正则表达式. 比如用户名: /1{3,16}$/

正则表达式在js中的使用:

正则表达式的创建:

在 JavaScript 中,可以通过两种方式创建一个正则表达式。

方式一:通过调用RegExp对象的构造函数创建
var regexp = new RegExp(/123/);
console.log(regexp);
方式二:利用字面量创建 正则表达式
 var rg = /123/;
测试正则表达式:

test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符串。

var rg = /123/;
console.log(rg.test(123));//匹配字符中是否出现123  出现结果为true
console.log(rg.test('abc'));//匹配字符中是否出现123 未出现结果为false

正则表达式中的特殊字符:

正则表达式的组成:

一个正则表达式可以由简单的字符构成,比如 /abc/,也可以是简单和特殊字符的组合,比如 /ab*c/ 。其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如 ^ 、$ 、+ 等。

特殊字符非常多,可以参考:
jQuery 手册:正则表达式:
边界符:

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

边界符说明
^表示匹配行首的文本(以谁开始)
$表示匹配行尾的文本(以谁结束)

如果 ^和 $ 在一起,表示必须是精确匹配。

var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^abc/;
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false
字符类:

字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。

[] 方括号:

表示有一系列字符可供选择,只要匹配其中一个就可以了

var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
var rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b  或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//true
----------------------------------------------------------------------------------
var reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true  - 表示的是a 到z 的范围  
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
-----------------------------------------------------------------------------------
//字符组合
var reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true  
------------------------------------------------------------------------------------
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true
量词符:

量词符用来设定某个模式出现的次数。

量词说明
*重复0次或更多次
+重复1次或更多次
重复0次或1次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
用户表单验证:

功能需求:

  1. 如果用户名输入合法, 则后面提示信息为: 用户名合法,并且颜色为绿色
  2. 如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为红色

分析:

  1. 用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为6~16位.
  2. 首先准备好这种正则表达式模式/$[a-zA-Z0-9-_]{6,16}^/
  3. 当表单失去焦点就开始验证.
  4. 如果符合正则规范, 则让后面的span标签添加 right类.
  5. 如果不符合正则规范, 则让后面的span标签添加 wrong类.
<input type="text" class="uname"> <span>请输入用户名</span>
 <script>
 //  量词是设定某个模式出现的次数
 var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 中划线
 var uname = document.querySelector('.uname');
 var span = document.querySelector('span');
 uname.onblur = function() {
   if (reg.test(this.value)) {
   console.log('正确的');
   span.className = 'right';
   span.innerHTML = '用户名格式输入正确';
   } else {
   console.log('错误的');
   span.className = 'wrong';
   span.innerHTML = '用户名格式输入不正确';
   }
 }
</script>
括号总结:

1.大括号 量词符. 里面表示重复次数

2.中括号 字符集合。匹配方括号中的任意字符.

3.小括号表示优先级

预定义类:

预定义类指的是某些常见模式的简写方式.

// 某些常见模式的简写方式.
// [0-9]   数字字符  \d
var reg = /^[0-9]$/ //等同于   /^\d$/

//  [^0-9]  非数字字符  \D
//  .  [^\r\n]  除了回车和换行符之外的所有字符
//  \s   [\t\n\x0B\f\r]  空白符
// [^\t\n\x0B\f\r]   \S   非空白符
// \w   [a-zA-Z_0-9]  字母数字下划线
//  \W  [^a-zA-Z_0-9]  非字母数字下划线
案例:验证座机号码
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;

表单验证案例
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
 if (reg.test(this.value)) {
    // console.log('正确的');
    this.nextElementSibling.className = 'success';
    this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
       // console.log('不正确');
      this.nextElementSibling.className = 'error';
      this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请从新输入 ';
 }
//QQ号验证: /^[1-9]\d{4,}$/; 
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
 function regexp(ele, reg) {
    ele.onblur = function() {
      if (reg.test(this.value)) {
        // console.log('正确的');
        this.nextElementSibling.className = 'success';
        this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
     // console.log('不正确');
     this.nextElementSibling.className = 'error';
     this.nextElementSibling.innerHTML = '<i class="error_icon"></i> 格式不正确,请从新输入 ';
            }
        }
 };
//密码验证:/^[a-zA-Z0-9_-]{6,16}$/
//再次输入密码只需匹配与上次输入的密码值 是否一致
修饰符:
g  global  全文搜索  不添加,搜索到第一个匹配为止

i   ignore case  忽略大小写 ,默认大小写敏感

m   multiple lines   多行搜索
正则替换replace:

replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。

var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
//全部替换g
var nStr = str.replace(/a/a,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"
案例:过滤敏感词汇
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
    var text = document.querySelector('textarea');
    var btn = document.querySelector('button');
    var div = document.querySelector('div');
    btn.onclick = function() {
    	div.innerHTML = text.value.replace(/激情|gay/g, '**');
    }
</script>

let声明变量:

let声明的变量具有块级作用级(在一个大括号中,使用let声明的变量才具有块级作用域 var是不具有这个特点的)

防止循环变量变成全局变量

使用let声明的变量没有提升(上面的赋值都会报错)

使用let声明的变量具有暂时性死区的特性

/* 
      let关键字就是用来声明变量的
      let声明的变量具有块级作用域
      在一个大括号中,使用let声明的变量才具有块级作用域 var是不具有这个特点的
      防止循环变量变成全局变量
      使用let声明的变量没有变量的提升
      使用let声明的变量具有暂时性死区的特性
      */

let a = 9
console.log(a)
let str = 'hello'
let flag = true
let num = 10
// ----------------let声明的变量具有块级作用域  {}
if (3 > 2) {
    let aa = 34
    var bb = 23
    }
console.log(bb) //23
// console.log(aa) //aa is not defined
// let声明的变量只在它所在的代码块内有效的

for (var i = 1; i <= 100; i++) {}
console.log(i) //10

for (let j = 1; j <= 100; j++) {
    // j只在循环体内有效,
}
// 循环体外使用就会报错
// console.log(j) //j is not defined

循环点击事件:

var btns = document.querySelectorAll('button')

// for (var k = 0; k < btns.length; k++) {
//   btns[k].index = k
//   btns[k].onclick = function () {
//     console.log(this.index, '下标')
//   }
// }

// for (var k = 0; k < btns.length; k++) {
//   ;(function (k) {
//     btns[k].onclick = function () {
//       console.log(k, '下标')
//     }
//   })(k)
// }
/* 
       每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,
      */
for (let k = 0; k < btns.length; k++) {
    // 此处就是点击事件的上一级作用域
    // 点击事件输出的是自己上一级(循环产生的块级作用域)作用域下的值
    btns[k].onclick = function () {
        console.log(k, '下标')
    }
}
/* 
       每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,
      */
for (let k = 0; k < btns.length; k++) {
    // 此处就是点击事件的上一级作用域
    // 点击事件输出的是自己上一级(循环产生的块级作用域)作用域下的值
    btns[k].onclick = function () {
        console.log(k, '下标')
    }
}

// 使用let声明的变量没有变量的提升
console.log('----------------------')

// console.log(f) //Cannot access 'f' before initialization
// let f = 4
// 暂时性死区
// 只有块级作用域内存在let命令,它所声明的变量就 绑定 这个区域,不受外部影响
// let 声明变量之前,该变量都是不可用的,---暂时性死区
console.log('----------------------')
var t = 134
if (true) {
    t = 'abc' //Cannot access 't' before initialization
    let t
    }

不能重复声明:

// 不能重复声明
// let l = 90
// let l = 23

const声明变量:

const声明的变量是一个常数

常量是不能重新进行赋值,如果是基本数据类型不能更改值,复杂数据类型 不能更改地址值,声明const的时候必须要给定值

// const PI   //Missing initializer in const declaration
const PI = 3.1415926
console.log(PI)
// PI = 222 //Assignment to constant variable

const arr = []
arr[0] = 23
arr[1] = 2
arr.push(123)
console.log(arr)

const obj = {
    name: '张叔叔',
}

数组解构:

// var aa = 2
// var bb = true
// var cc = 'hello'
// 从数组中提取值,按照位置,给变量赋值
// // let [aa, bb, cc, dd] = [2, true, 'hello']
// console.log(aa, bb, cc)
// console.log(dd) //undefined

// let [aa, bb, cc, dd] = [2, true, 'hello', 1, 34]
// console.log(aa, bb, cc)

// 嵌套数组进行解构
// let [a, [b, c]] = [1, ['22', '33']]
// console.log(a, b, c)

// let [a, [[b], c]] = [1, [[2], 3]]
// console.log(a, b, c) //1 2 3

let [a] = []
let [c, b] = [2]
// 以上两种都属于解构不成功 a的值等于undefined   b的值为undefined

对象解构:

// let { name } = { name: '张三' }
// console.log(name)

// let obj = {
//   name: 'ls',
//   age: 23,
//   sex: '男',
//   score: 100,
// }

// // 变量名和对象的属性名要一一对象
// let { name, sex, age, score, a } = obj
// console.log(a) //undefined

let obj = {
    name: 'ls',
    age: 23,
    sex: '男',
    score: 100,
    msg: {
        des: 'hello',
    },
}

let {
    name,
    age,
    sex,
    score,
    msg,
    msg: { des },
} = obj

console.log(des) //hello
console.log(msg)

对象可以设置默认值:

默认值生效的条件

对象的属性严格等于undefined

let { x = 3 } = {}
// console.log(x) //默认值

let { y, w = 9 } = { y: 3 }
// console.log(y, w) //3  9

// m是xx的别名
let { xx: m } = { xx: 23 }
// console.log(m)

注意:设置别名之后只能使用别名

字符串的解构:

字符串被转换成了一个类似数组的对象

const [q, e, r, t] = 'hell'
// console.log(q, e, r, t) //h   e   l   l
// 类似数组的对象 都有一个length属性,可以对length属性进行解构
let { length: len } = 'hello world'
// console.log(len) //11

函数参数的解构赋值:

function fn([a, b]) {
    return a + b
}

fn([1, 2])

function fun({ name, age }) {
    return name + age
}
var o = fun({ name: '张三', age: 12 })
console.log(o)

箭头函数:

作用:

1、简写形式

2、改变this指向

=> 定义函数

注意:

事件函数不能用箭头函数(this指向会变成window)

定义对象不适合箭头函数(会报错)

/*
        箭头函数
        作用  :1 简写形式    2:改变this指向
      */

//    => 定义函数

// var fn = function () {
//   console.log(123)
// }

// var fn = () => {
//   console.log(123)
// }
// fn()
// -----------------------------------
// var fn = function (a) {
//   return a
// }

// var fn = a => {
//   return a
// }

// var fn = (a) => a
// ----------------------------有多个参数
// var fn = function (a, b) {
//   return a + b
// }

// var fn = (a, b) => a + b
// console.log(fn(1, 2))
// --------------函数的代码块有多条语句
// var fn = function (a, b) {
//   console.log(a + b)
//   return a + b
// }

// var fn = (a, b) => {
//   console.log(a + b)
//   return a + b
// }

// ----------------代码块有一条语句 返回的是一个对象,对象要用括号括起来
// var fn = function () {
//   return { name: '张三', age: 23 }
// }

// var fn = () => ({ name: '张三', age: 23 })
// console.log(fn())

// ;[1, 2, 3].map(function (item) {
//   return x * 2
// })

// ;[1, 2, 3].map((item) => item * 2)
// var newArr = [1, 2, 3, 4]
//   .filter((item) => item % 2 === 0)
//   .map((x) => x * 2)

// console.log(newArr)

/*

        箭头函数this指向
          箭头函数不绑定this关键字,在箭头函数中使用this。this指向箭头函数定义位置中的this
          箭头函数优点 在于解决了 this执行环境所造成的一些问题
          解决了匿名函数this指向的问题,(匿名函数的执行环境具有全局性)包括setTimeout和setInterval中
          使用this所造成的问题


        注意:箭头函数不可以当做构造函数,不可以对箭头函数使用new命令,否则会抛出错误
      */

const btns = document.querySelectorAll('button')

// for (let i = 0; i < btns.length; i++) {
//   btns[i].onclick = function () {

//     setTimeout(() => {
//       this.style.color = 'red'
//     }, 1000)
//   }
// }

// function fun() {
//   setTimeout(() => {
//     console.log(this, this.id)
//   }, 100)
// }
// var o = { id: 3 }
// fun.call(o)

// ------------
// 绑定事件不适合使用箭头函数
btns[0].onclick = () => {}
// 定义对象的方法 不适合使用箭头函数
var obj = {
    name: '张三',
    run: () => {
        console.log(this.name)
    },
}
console.log(obj.run()) //this指向window

函数参数的默认值:

函数默认值(若有传实参则为传的值)

// es6之前,不能直接为函数的参数指定默认值

// function fn(a, b) {
//   b = b || '123'
//   console.log(a, b)
// }
// fn(1, 2)
// fn(1)
// es6允许为函数的参数设置默认值,直接写在参数定义的后面
// function fn(a, b = '123') {
//   console.log(a, b)
// }
// fn(1, 3)
// fn(2)
// fn(4, '')

// 和解构赋值默认值结合使用
// function fn({ x, y = 10 }) {
//   console.log(x, y)
// }
// fn({}) //undefined 10
// fn({ x: 12 }) //12 10
// fn({ x: 12, y: 23 }) //12 23
// fn() //annot destructure property 'x' of 'undefined' as it is undefined.

// 默认值的位置
function fn(x = 12, y) {
    console.log(x, y)
}

fn() //12 undefined
fn(23) //23 undefined
// fn(,23)  报错
fn(undefined, 12) //12 12

扩展运算符:

将数组和对象元素进行展开

/* 
扩展运算符   
   ...  将数组或者对象元素进行展开


  可以将多个数组进行合并  [...数组1,...数组2]
  使用push的方式
*/

// var arr1 = [1, 2, 3]
// console.log(...arr1) //1 2 3
// var arr2 = [3, 4, 5]
// var newArr = [...arr1, ...arr2]

// arr1.push(...arr2)
// console.log(arr1)

var o = {
    name: '张三',
    age: 12,
}
var obj = {
    ...o,
    sex: '男',
}
console.log(obj)

// function show(a, b, c) {
//   console.log(a, b, c)
// }

// let arr = [11, 22, 33]
// show(...arr)

// 不知道参数的个数
function demo(...args) {
    console.log(args)
}

demo(1, 2, 3, 4, 5, 6, 7, 8)

数组的扩展:

Array.from:

将伪数组转换成真正的数组

/* 
      Array.from  把伪数组转换为真正的数组
      */

// let arr = {
//   0: 'hello',
//   1: 123,
//   2: true,
//   length: 3,
// }
// let arr2 = Array.from(arr)
// console.log(arr2) //['hello', 123, true]
let pArr = document.querySelectorAll('p')
let newArr = Array.from(pArr).filter((item) => {
    return item.textContent.length > 3  // 将每一个p节点的value值长进行判断
})
console.log(newArr)

模板字符串:

使用 ${参数}

function fn(age) {
    var s = age > 20 ? '青年' : '未成年'
    return s
}
var arr = [
    { id: 1, name: '张三', age: 12 },
    { id: 2, name: '李四', age: 22 },
    { id: 3, name: '王五', age: 33 },
    { id: 4, name: '赵六', age: 44 },
]
let str = ''
arr.forEach((item) => {
    // str +=
    // ' <li><p>姓名:' + item.name + '</p><p>年龄:' + item.age + '</p></li>'

    str += `
    <li>
    <p>姓名:${item.name}</p>
    <p>年龄:${item.age}</p>
    <p>${fn(item.age)}</p>
    </li>
	`
})

var oul = document.querySelector('#oul')
oul.innerHTML = str

字符串的扩展:

includes(字符串,start) 判断父串中是否包含子串的内容,返回布尔值

startsWith(字符串,start) 判断父串中是否以指定的子串开头,返回布尔值

endsWith(字符串,start) 判断父串中是否以指定的子串结尾,返回布尔值

repeat() 重复指定的字符串,返回字符串

var str = 'how do you do'
console.log(str.includes('do', 4)) //true
console.log(str.startsWith('do', 4)) //true
console.log(str.endsWith('do', 6)) //true

var ch = 'o'
console.log(ch.repeat(3)) //"ooo"
console.log(ch.repeat(3.3)) //"ooo"
// console.log(ch.repeat(-3)) //报错 Invalid count value
console.log(ch.repeat(-0.3)) //""

symbol:

es6新增了第7种基本数据类型Symbol

Symbol符号,象征,标记,记号,在js中独一无二的值

// symbol 是独一无二的
const s = Symbol()
const s1 = Symbol()
// console.log(typeof s) //symbol
// console.log(s === s1) //false

// Symbol方法接收一个参数,表示对生成symbol值的一种描述

// 传入相同的参数,生成的symbol的值也是不相等的
const foo = Symbol('foo')
const bar = Symbol('foo')
console.log(foo === bar) //false

// 场景
// 1[重点] 作为对象的属性 一个复杂的对象有多个属性的时候,很容易将某个属性名覆盖,利用symbol值作为属性名可以避免

const name = Symbol('name')
const obj = {
    // 对象以变量作为属性名  用到[]
    [name]: 'lucy',
}
// 2 Es6中的类是没有private关键字来声明类的私有方法和私有变量的,可以使用symbol的唯一性来模拟
const speak = Symbol()
class Person {
    [speak]() {
        // ...
    }
}

set:

es6提供了新的数据解构 Set,类似于数组,但是成员的值都是唯一的,没有重复的值

set.add(value) 添加元素到集合内
set.delete(value) 删除指定的元素
set.clear() 清空集合内元素
set.forEach(callback) 遍历集合内所有元素
set.has(value) 检查集合内是否有某个元素

set无序 元素不可重复

array 有序 元素可以重复

/*
      数组是有序的集合,每个元素可以使用数字下标的形式获取,但是在一些业务场景中,需要无序集合,
      es6 就有了set无序集合(没有排序的数组,元素具有不可重复的特性)
      */

// Set本身是一个构造函数,用来生成set数据结构

let set = new Set('hello')
// console.log(set)
set.add(12) //add 给set结构添加成员
console.log(set.has('h')) //true   判断set结构是否有某个成员
console.log(set.size) // 获取长度

set.delete(12) //删除指定的set结构成员
console.log(...set)
set.clear() //删除所有的成员

/*

             set   无序  元素不可重复
             array 有序  元素可重复

             set常用的方法
             set.add(value)  添加元素到集合内
             set.delete(value) 删除指定的元素
             set.clear() 清空集合内元素
             set.forEach(callback) 遍历集合内所有元素
             set.has(value)  检查集合内是否有某个元素
            */

const set1 = new Set()
set1.add(1).add(2).add(3).add(3)
console.log(...set1) //1  2   3
// 删除指定的元素
set1.delete(2)
console.log(...set1) //1  3
// 清空集合内元素
set1.clear()
console.log(...set1)

// 检查元素
const set2 = new Set([1, 2, 3, 4])
console.log(set2.has(5))

// 遍历集合内所有元素   set集合没有键名 只有键值
let ss = new Set(['red', 'green', 'yellow', 'blue'])

// for (let item of ss.keys()) {
//   console.log(item)
//   // red
//   // green
//   // yellow
//   // blue
// }

// for (let item of ss.values()) {
//   console.log(item)
//   // red
//   // green
//   // yellow
//   // blue
// }

// for (let item of ss.entries()) {
//   console.log(item)
//   // ['red', 'red']
// }

ss.forEach((item) => {
    console.log(item)
    // red
    // green
    // yellow
    // blue
})

// 实现数组去重
// let arr = new Set([3, 4, 5, 5, 2, 3, 2, 5]).values()
let arr = Array.from(new Set([3, 4, 5, 5, 2, 3, 2, 5]))
console.log(arr)  // [3, 4, 5, 2]

map:

对象的属性只能是字符串类型

数据不能重复,并且必须是键值对

// 对象的属性名只能是字符串类型
const o = {}
const ele = document.querySelector('div')
o[ele] = 'element' //ele 被自动转换为字符串

// es6提供了map数据结构,类似于对象  属性名(键)的范围不限于字符串,各种类型的值都可以作为键

const m = new Map()
const oo = { name: 'hello world' }
// 添加成员
m.set(oo, 'content')   //键   键值
console.log(m)
// 获取
console.log(m.get(oo)) //"content"
// 判断是否有该键
console.log(m.has(oo)) //true

// 删除
m.delete(oo)
console.log(m.size) // 0   获取数据的数量

// 一个key只能对应一个value  多次对一个key放入value  后面的值会把前面的值覆盖

var map = new Map()
map.set('a', '女')
map.set('a', '男')
console.log(map)

map和set的区别:

具有极快的查找速度

map需要的是一个二维数组 set需要的是一个一维数组

map是键值对 set没有value只有key

// 1 具有极快的查找速度

// var arr = new Array()
// var set = new Set()
// var map = new Map()

// for (var i = 0; i < 30; i++) {
//   arr[i] = i
//   set.add(i)
//   map.set(i, arr[i])
// }
// console.log('---------------------------')

// console.time()
// for (var j = 0; j < 30; j++) {
//   arr.includes(j)
// }
// console.timeEnd()

// console.time()
// for (var j = 0; j < 30; j++) {
//   set.has(j)
// }
// console.timeEnd()
// console.time()
// for (var j = 0; j < 30; j++) {
//   map.has(j)
// }
// console.timeEnd()

// 2 map需要的是一个二维数组  set需要的是一个一维数组
// map  和set都不需要键重复

const map = new Map([
    ['name', '张三'],
    ['age', 12],
])

const set = new Set([2, 3, 4, 5])

// map是键值对  set没有value只有key

set去重:

let s = new Set([1, 2, 1, 4, 5, 2, 3, 1, 4])
const arr = [...s]
// console.log(arr) //[1, 2, 4, 5, 3]

map去重:

let arr1 = [1, 2, 1, 4, 5, 2, 3, 1, 4]
const mm = new Map()
let res = arr1.filter((item) => !mm.has(item) && mm.set(item, 1)) // 判断每一个数值,如果在mm中不存在,前面为true则执行后面的程序,向mm中添加键和值(1,1),当遇到mm中有的数据,前面为false,直接过滤掉数据
console.log(res) //[1, 2, 4, 5, 3]

  1. a-z0-9_- ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跨界科技汇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值