JavaScript-ES6

ES6

自动严格模式

//使用严格模式  必须写在最上面
"use strict"
1. 使用严格模式后,变量必须使用varlet定义,不能直接写变量

2. this在函数中严格模式时(最顶层不是在window),不再指向window,而指向undefined
	//严格模式下
	function fn(){
         console.log(this)
      }
      fn()//undefined
	
	var arr=[1,2,3,4]
      arr.forEach(function(item){
         console.log(this)//全是undefined
      })


	//去掉严格模式时
	 var a=1
      function fn(){
         var a=2
         console.log(this.a+a)//3
      }
//此时this指向a=1 所以得 1+2=3
      fn()


//严格模式时,如果call或apply传入的第一个参数是什么就指向什么
      function fn(){
         console.log(this)
      }
      fn.call(null)//null
      fn.call(undefined)//undefined
      fn.call(1)//1
//非严格模式下null、undefined的this指向window,this指向引用型数值对象1
      function fn(){
         console.log(this)
      }
      fn.call(null)//window
      fn.call(undefined)//window
      fn.call(1)//Number{1}

3.禁止使用argument.callee,fn.caller
	//严格模式下
	function fn(){
         console.log(arguments.callee)//报错
         console.log(fn.caller)//报错
      }
      fn()
4.禁止使用with
      var obj={
         o:{
            a:1,
            b:2
         }
      }
      console.log(obj.o.a)//1

//with非严格模式下只能修改该对象下已有的属性,如果不是已有默认创建一个全局变量
	//严格模式下会报错
      with(obj.o){
         a=3;
         b=4;
         c=5;
      }
      console.log(c)//5

5.禁止使用o作为八进制写法
      var a=o5;//早期使用,现在被禁止
      var a=0o5;//现在可以使用的

6.禁止使用eval(官方文档是禁止重新定义eval和将eval的内容指向顶层)
      var o={a:1}
      var a=1;
      var b=2;
      //var eval=3;//报错

      //将字符串转换为js语句
	 //效率不高
      console.log(eval("o"))//{a:1}
      console.log(eval("a+b"))//3

	//eval不能转换函数 反射
      var fn = eval("function fn({console.log('aaa')}")
      console.log(fn)//undefined

	//反射
      function getValue(a, b, type) {
         return (eval(a + type + b))
      }
      var sum = getValue(3, 5, "-")
      console.log(sum)//-2

字符串模板

	  var str="a"
      var str1='a'
      var str2=`a`//字符串模板
      
      //双引号和单引号 无法换行
      var str="<div>
          </div>"  //报错
      
      //使用字符串模板可以换行
      var str=`<div>
         	<span></span>
         	</div>`
      
      //双引号和单引号如果和变量组合使用,就必须使用字符串拼接才可以连接
      //字符串模板使用${ }
      var age = 30;
      var str = "我今年" + age + "岁了"
      var str1 = `我今年${age}岁了`
      console.log(str, str1)

案例1

var arr = [
      { href: "http://www.baidu.com", site: "百度" },
      { href: "http://www.tencent.com", site: "腾讯" },
      { href: "http://www.taobao.com", site: "淘宝" },
      { href: "http://www.jd.com", site: "京东" },
      { href: "http://www.163.com", site: "网易" }
      ]

      var div1 = document.getElementById("div1")
  // reduce方式
      /div1.innerHTML = `<ul>
         ${arr.reduce(function (value, item) {
         return value + `<li><a href='${item.href} '>${item.site}</a></li>`
      }, "")}
         </ul>` 
      
  // map方式
      	div1.innerHTML = `<ul>
            ${arr.map(function (item) {
         return `<li><a href='${item.href}'>${item.site}</a></li>`
      }).join("")}
            </ul>`

案例2

var arr = [
         { content: "商品1", show: true },
         { content: "商品2", show: false },
         { content: "商品3", show: true },
      ]
      div1.innerHTML = `<ul>
         ${(function () {
            var str = ``;
            for (var i = 0; i < arr.length; i++) {
               str += `<li style='display:${arr[i].show ? "block" : "none"}'>${arr[i].content
                  }</li>`
            }
            return str;
         })()}
         </ul>`
      
      
   //方式2 把函数写在外面调用   
      div1.innerHTML = `<ul>
            ${fn()}
            </ul>`

      function fn() {
         var str = ``;
         for (var i = 0; i < arr.length; i++) {
            str += `<li style='display:${arr[i].show ? "block" : "none"}'>${arr[i].content}</li>`
         }
         return str;
      }

解构赋值

//这就是解构赋值
//原来是一个数组 通过解构之后  把里面的对象给一个个拿出来了
var arr = [
         { x: 10, y: 20 },
         { x: 30, y: 40 }
      ]
      var [point1, point2] = arr
      console.log(point1)//{x: 10, y: 20}
      console.log(point2)//{x: 30, y: 40}

数组解构

var arr = [1, 2]
      //将数组中的元素按位赋值给[]里面的变量
      var [a, b] = arr
      console.log(a, b)//1  2
//定义的 变量名要保持一致  即 上面是arr  下面也得是arr
      var arr = ["张三", "李四"]
      var [name1, name2] = arr
      console.log(name1, name2)//张三 李四
交换变量
//交换变量
      var x = 1;
      var y = 2;
      var arr = [x,y];//此处一定要加分号
      [y,x] = arr;
      // [x,y]=[y,x]  这个式子等同于上面两行
      console.log(x, y)// 2  1
默认值
 var [x,y]=[1,2,3]//1 2
 var [x,y,z]=[1,2]//1 2 undefined
 var [x,y,z=0]=[1,2]//1 2 0  虽然z没有给值 但是前面赋给了默认值所以是0
 var [x,y,z=0]=[1,2,3]//1 2 3 z给值了 0会被覆盖
      console.log(x,y,z)

//函数传参和上面一样
function fn(a,b,c=0){
         console.log(a,b,c)//1 2 0 
      }
      fn(1,2)
多维数组
//会把数组中的值一个一个拿出来
var [a, b, [c, d, [e, f]]] = [1, 2, [4, 5, [6, 7]]]
      console.log(a, c, b, d, e, f)//1 4 2 5 6 7

var [a,b,[c,d,arr]]=[1,2,[4,5,[6,7]]];
      console.log(arr)//(2) [6, 7]

对象解构

 	  var point1={x:10,y:20}
 	  var {x,y}=point1
      console.log(x,y)//10 20

      //对象按属性名解构,不分前后顺序
      //所以不会交换
      var {y,x}=point1
      console.log(x,y)//10 20
默认值
	  var o = { name: "张三", age: 20, sex: "男" }
      var { name, age, sex } = o
      console.log(name, age, sex)//张三 20 男

      //没有age属性
      var {name,sex}={name:"张三",age:20,sex:"男"}
      console.log(name,sex)//张三 男

      //给age属性赋默认值0	
      var {name,age=0,sex}={name:"张三",age:20,sex:"男"}
      console.log(name,age,sex)//张三 20 男



	function fn({ name, sex, age }) {
         console.log(name, sex, age)
      }
    fn({ name: "张三", sex: "男", age: 30 })//张三 男 30

      function fn({ name, sex, age = 0 }) {
         console.log(name, sex, age)
      }
    fn({ name: "张三", age: 40 })//张三 undefined 0
函数中对象解构做为参数
//在函数中如果参数是对象解构,使用函数传参时,可以不按照顺序传入内容,对象中的属性名对应就可以
//更灵活了  不用满足实参 形参一一对应
function fn({name,sex="男",age}){
         console.log(name,sex,age)
      }
      fn({name:"张三",age:40,sex:"女"})//张三 女 40
多复杂型
	var obj = {
         a: 1,
         b: 2,
         c: {
            d: 3,
            e: 4
         }
      }
      var {a,b,c:{d,e}}=obj
      //c被解构为后面的{d,e} c是不存在的
      console.log(a,b,d,e)//1 2 3 4

      //重新将c从对象中单独解构出来
      var {a,b,c:{d,e},c}=obj;
      console.log(a,b,c,d,e)//1 2 {d: 3, e: 4}3 4




	var obj = {
         a: 1,
         b: 2,
         c: {
            d: [3, 4],
            e: [5, 6]
         }
      }
  var { a, b, c: { d: [x, y], e: [m, n] } } = obj
  console.log(a, b, x, y, m, n)//1 2 3 4 5 6

  var { a, b, c: { d: [x, y], e: [m, n] ,d,e},c } = obj
      console.log(a, b, x, y, m, n,c,d,e)//1 2 3 4 5 6 {d: Array(2), e: Array(2)} (2) [3, 4] (2) [5, 6]
有重复属性名
//因为对象是按照属性名解构,要求变量名必须和属性名一致,多个对象中如果有同名的属性,这时候需要给变量 起别名
      var arr = [
         { x: 10, y: 20 },
         { x: 30, y: 40 }
      ]
      var [{ x, y }, { x: x1, y: y1 }] = arr
      console.log(x, y, x1, y1)//10 20 30 40


      var obj = {
         a: 1,
         b: 2,
         c: {
            a: 3,
            b: 4
         }
      }
      var { a, b, c: { a: a1, b: b1 } } = obj
      console.log(a, b, a1, b1)//1 2 3 4
起别名遇到默认值
 	  //b没赋值 但是有默认值0 就使用默认值
      var { a, b, c: { a: a1, b: b1 = 0 } } = { a: 1, b: 2, c: { a: 3 } }
      console.log(a, b, a1, b1)//1 2 3 0


      //b被赋值了 默认值0被覆盖
      var { a, b, c: { a: a1, b: b1 = 0 } } = { a: 1, b: 2, c: { a: 3, b: 4 } }
      console.log(a, b, a1, b1)//1 2 3 4
//传参问题


//如果函数的参数使用解构对象,但是函数没有传参,这时候无法解构对象,就会报错
//因此我们需要给解构对象一个默认值
	function fn({ a, b }) {
         console.log(a, b)
      }
      fn()//报错
      
      //给默认值 {}
      function fn({ a, b }={}) {
         console.log(a, b)//undefined undefined
      }
      fn()


//有默认值 但是没赋值 就使用默认值
 function fn({ a, b } = { a: 0, b: 0 }) {
         console.log(a, b)//0 0 
      }
      fn()
//因为没有传参 所以还是使用默认值
function fn({ a, b = 10 } = { a: 0, b: 0 }) {
         console.log(a, b)//0 0
      }
      fn()

//当传参时默认值对象{a:0,b:0}就无效了,将{a:5}给参数{a,b}做解构,但是只有a属性,没有b属性,b属性使用自身的默认值
function fn({ a = 5, b = 10 } = { a: 0, b: 0 }) {
         console.log(a, b)
      }
      fn()//0 0 
      fn({})//5 10 传参了但是 是空使用其初始值
      fn({ a: 1 })//1 10
      fn({ b: 100 })//5 100


function fn({ a = 5, b: { c = 1, d = 2 } = { c: 5, d: 6 } } = { a: 0, b: {} }) {
         console.log(a, c, d)
      }
      fn()//0 1 2 此时没传参 使用默认值对象 a=0 b={} -> 相对于给传参了所以使用自身的默认值
      fn({ a: 10 })//10 5 6 此时传参了不使用默认值对象  给a赋值 但没有给b 所以b使用其默认对象
      fn({})// 5 5 6 传参了不使用默认值对象 但是是空a无默认值对象所以等于其默认值  b使用其默认值对象
      fn({ b: { d: 10 } })//5 1 10   传参了不使用默认值对象 a同上  b给值了所以使用自身对象

箭头函数

箭头函数不会预解析,所以不许先定义后使用

写法

	var fn = function () {

      }
      //箭头函数
      var fn = () => {

      }

      var fn = function (a, b) {
         console.log(a, b)
      }
      var fn = (a, b) => {
         console.log(a + b)
      }
      
      
      
//如果函数中的参数仅有一个,可以省略小括号
//但是如果函数中没有参数,或者函数参数超过一个,就必须写小括号
      var fn=function(a){
         console.log(a)
      }

      var fn=a=>{
         close.length(a)
      }
      
 //如果函数仅有一句话,就可以省略{}包括这句话的return
 //省略{}相当于加了一个return      
	 var fn=function(a,b){
         return a+b
      }
      var fn=(a,b)=>a+b
      
      
   	  var fn=function(a,b){
          console.log(a+b);
      }
      var fn=(a,b)=>console.log(a+b);



var fn = function (name, age, sex) {
         // 在写对象时,如果键名等于变量名
         // return {
         //     name:name,
         //     age:age,
         //     sex:sex
         // }
         //可以省略键名 下面等同于上面
         return {
            name,
            age,
            sex
         }
      }

      //错误写法  这里把{}看做函数的{}
      // var fn=(name,age,sex)=>{name,age,sex};

      //错误写法 不能有return
      // var fn=(name,age,sex)=>return {name,age,sex};

      //正确写法  需要加一个()
      var fn = (name, age, sex) => ({ name, age, sex });
      var o = fn("张三", 30, "男");
      console.log(o)//{name: '张三', age: 30, sex: '男'}

使用方式

	var fn=function(a,b){
         a++;
         b++;
         return a+b
      }
      
      var fn=(a,b)=>(a++,b++,a+b)
      console.log(fn(3,4))//9


	var arr = [2, 5, 2, 1, 4, 6, 8, 9];
      arr.sort((a, b) => a - b)
      var arr1 = arr.map(item => item + 10)
      console.log(arr1)//(8) [11, 12, 12, 14, 15, 16, 18, 19]
      if (arr.some(item => item > 5)) {
         console.log("Aa")//Aa
      }

箭头函数this的指向

//箭头函数使用的特征,改变箭头函数中的this指向

/* 
在箭头函数中,this指向,父级程序的this指向
如果父级程序有this指向,那么箭头函数指向的就是父级程序的this
如果父级程序没有this指向,那么指向的就是window
*/

//严格模式下 普通函数this指向undefined   箭头函数还是指向window
      var fn = function () {
         console.log(this);
      }
      var fn = () => {
         console.log(this);//window
      }
      fn()

      var obj = {
         a: 1,
         b: function () {
            // console.log(this);
            var fn = () => {
               console.log(this);//obj
            }
            fn();
         }
      }
      obj.b();


      var a = 10;
      var obj = {
         a: 1,
         name: this.a,//this 对象外的this的指向
         b: function () {
            console.log(this)
         },
         c() {
            console.log(this)
            // 在对象中直接写一个 函数名(){} 和写入 方法名:function(){} 完全相同
         },
         d: () => {
            console.log(this);//对象外的this指向  window
         }
      }
      obj.b()//obj
      obj.c()//obj
      obj.d()//window

展开语法

作用

var arr=[1,2,3,4]
      console.log(arr)//(4) [1, 2, 3, 4]
      console.log(...arr)//1 2 3 4



	 var arr=[0]
      var arr1=[1,2,3]
      //push向数组中添加新元素,不会改变原数组
      //把arr1 展开后 把值添加到arr
      arr.push(...arr1)
		//此时只是改变了其值 并没有改变引用地址
      console.log(arr)//(4) [0, 1, 2, 3]

		//使用concat 返回一个新数组,重新赋值给arr,这就把原来的arr数组给覆盖
		//引用地址改变了
      arr=arr.concat(arr1)
      console.log(arr)//(4) [0, 1, 2, 3]


//实现让arr1的值覆盖arr的值
	 var arr = [1, 2, 3, 4]
      var arr1 = [4, 5, 6, 7]
      arr.length = 0;
      arr.push(...arr1)
      console.log(arr)//(4) [4, 5, 6, 7]	

复制数组
//复制数组
      var arr=[1,2,3,4]
      //concat,map两个方法都会返回新数组
      var arr1=arr.concat()
      var arr2=arr.concat()
      console.log(arr1)//(4) [1, 2, 3, 4]
      console.log(arr2)//(4) [1, 2, 3, 4]
      var arr3=arr.map(item=>item)
      console.log(arr3)//(4) [1, 2, 3, 4]

      //使用展开语法复制数组
      var arr=[1,2,3,4]
      var arr1=[...arr]
      console.log(arr1)//(4) [1, 2, 3, 4]

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

求最大值
var arr=[1,5,2,7,3,8]
      var max=Math.max.apply(null,arr)//8
      var max=Math.max(...arr)//8
      console.log(max)

在函数中的使用
	 //在实参中使用...
      function fn(a, b, c) {
         console.log(a, b, c)//1 2 3
      }
      var arr = [1, 2, 3]
      fn(...arr)

      //在形参中使用...
      // 在形参中使用...语法,就是把实参聚合成一个数组
      function fn(...arg) {
         console.log(arg)//(3) [1, 2, 3]
      }
      fn(1, 2, 3)

案例 判断参数类型
/* 
 1、必填参数  参数必须写入实参,如果不写会出现错误
 2、默认值参数 参数如果没有实参,会自动赋值默认值
 3、选填参数 参数为选填,如果没有实参,不会引起函数错误
 4、剩余参数 如果除了前面参数以外,还想多填充其他参数,将会归入剩余参数  ...arg
*/

function fn(a, b = 1, c, ...arg) {
         // a 必填参数  b 默认值参数 c 选填参数  arg 剩余参数
         if (typeof a !== "number" || typeof b !== "number") throw new TypeError("a 或者 b 不是数值!")
         var s = a + b;
         if (c !== undefined) {
            if (typeof c !== "number") throw new TypeError("c 不是数值!")
            s += c;
         }
         if (arg.length > 0) {
            if (arg.every(item => typeof item !== "number")) throw new TypeError("c 不是数值!")
            s += arg.reduce((v, t) => v + t)
         }
         return s
      }
      console.log(fn(1))
      console.log(fn(1, 2))
      console.log(fn(1, 2, 3, 4, 5, 6, 7))

对象展开语法

浅复制
var obj = {
         a: 1,
         b: 2,
         c: 3,
         d: {
            e: 10
         }
      }
      //浅复制     对象的第一层是没有引用关系的,第二层及以后都是还有引用关系,
      var o = { ...obj }
      obj.a = 10;
      obj.d.e = 100
      console.log(o)//{a: 1, b: 2, c: 3, d: {e:100}}

连接对象
var o1 = { a: 1, b: 2 }
      var o2 = { c: 3, d: 4 }
      var o3 = { ...o1, ...o2, e: 10 }
      console.log(o3)//{a: 1, b: 2, c: 3, d: 4, e: 10}

解构与展开语法的区别

//解构:解构赋值允许你使用数组或对象字面量的语法,将数组和对象的属性付给各种变量。

//展开:允许你讲一个数组展开为另一个数组,或一个对象展开为另一个对象。

Set

知识点补充:

数据结构 数据在存储过程中的存储方式
Array Object
Array 存储按位存储,紧密结构,在数组中查找元素,就必须要遍历数组,优点可以根据当前元素 找到前一个或者后一个元素,可以排序

Object 按键存储,松散结构(删除其中一个属性,不会影响其他属性的位置),添加、删除、查找速度极快
缺点:无法找到相邻关系数据,无法排序

set的方法

//Set 类似于数组   Set是集合,松散型结构,不能排序。集合存储仅有元素,而且仅能存储不重复的元素
      var s=new Set([1,2,3,4,5])
      // 把数组做为Set参数,会自动把数组元素放在set对象中
      //相当于数组的length
      console.log(s.size)//5




var s = new Set();
      //s.add向集合中添加元素 返回集合对象自身
      //每次只能添加一个,如果添加的元素在数组中已经存在,就不在添加
      s.add(1)
      s.add(2)
      s.add(3)
      s.add(4)
      s.add(2)
      console.log(s)//Set(4) {1, 2, 3, 4}

      console.log(s.has(3))//true 判断集合中是否有该元素

      s.delete(3)// 删除集合中的元素
      console.log(s)//Set(3) {1, 2, 4}

      s.clear()// 清空集合中的元素
      console.log(s)//Set(0) {size: 0}

      //遍历集合
      s.forEach(item => {
         console.log(item)
      })

for of

//for of 类似for in,但是这里for(var value of s) value就是每个元素  可以用来遍历所有的迭代器

	var s = new Set();
      s.add(1)
      s.add(2)
      s.add(3)
      s.add(4)
      for (var value of s) {
         console.log(value)
      }
      console.log(s)


      var arr = [1, 2, 3, 4, 5];
      for (var value of arr) {
         console.log(value)
      }

set的用法

1.数组去重
 	var arr = [1, 2, 5, 2, 3, 5, 1, 3, 5, 7, 9];
      arr = Array.from(new Set(arr))
      console.log(arr)//(6) [1, 2, 5, 3, 7, 9]

      var arr = [
         { id: 1, name: "商品1", price: 3000 },
         { id: 2, name: "商品2", price: 4000 },
         { id: 1, name: "商品1", price: 3000 },
         { id: 3, name: "商品3", price: 5000 },
         { id: 4, name: "商品4", price: 6000 },
      ]
      var s = new Set(arr)
      //每个对象的引用地址都是不同的
      console.log(s)

2.不会因为塌陷造成处理问题
var arr = [
         { id: 1, name: "商品1", price: 3000 },
         { id: 2, name: "商品2", price: 4000 },
         { id: 3, name: "商品3", price: 5000 },
         { id: 1, name: "商品1", price: 3000 },
         { id: 4, name: "商品4", price: 6000 },
         { id: 2, name: "商品2", price: 4000 }
      ]
      var s = new Set(arr)
      for (var i = 0; i < arr.length; i++) {
         var index = arr.slice(i + 1).findIndex(item => item.id == arr[i].id)
         if (index > -1) {
            index += i + 1;
            arr.splice(index, 1)
         }
      }
      console.log(arr)

3.增改查
//不使用set
	var arr=[];
      function add(f){
          if(arr.includes(f)) return;
          arr.push(f);
      }

      function remove(f){
         var index=arr.indexOf(f);
         if(index<0) return;
         arr.splice(index,1);
      }

      function callAllFn(){
          arr.forEach(fn=>{
              fn();
          })
      }

      function fn1(){
          console.log("fn1");
      }
      function fn2(){
          console.log("fn2");
          remove(fn2);
      }
      function fn3(){
          console.log("fn3");
      }

      add(fn1);
      add(fn2);
      add(fn3);
      add(fn2);

      console.log(arr)

      callAllFn();
      
      
 //使用set
      var s=new Set();
    function add(f){
       s.add(f)
    }

    function remove(f){
       if(s.has(f)) s.delete(f);
    }

    function callAllFn(){
        s.forEach(fn=>
            fn()
        )
    }


    function fn1(){
        console.log("fn1");
    }
    function fn2(){
        console.log("fn2");
        remove(fn2);
    }
    function fn3(){
        console.log("fn3");
    }

    add(fn1);
    add(fn2);
    add(fn3);
    add(fn2);

    // console.log(arr)

    callAllFn();
    callAllFn();

WeakSet 弱引用集合

var s=new WeakSet();
    /* 只有添加、删除、清空
    必须只能添加引用类型
    不能被遍历 forEach、for of不能遍历 */
    s.add({a:1,b:2});
   //  s.add()
   //s.delete();
   //  s.clear();
    console.log(s)


    var o={a:1,b:2};
    var o1=o;
   //  强引用关系
    o=null;
    console.log(o1);//o被清除 o1不变

Map

理念

map 映射对象
键值对 松散结构 对象的key只能是字符串或者symbol,但是map的key可以是任何类型,增删改查速度快
可以做任何关联关系,map可以单独遍历key,或者单独遍历valuemap也有size,对象是没有length

	var m=new Map()
      m.set("a",1)//给m设置了一个字符串a属性,并且值设置为1
      m.set(false,2)//给m设置了一个字符串false属性,并且值设置为2
      var o={a:1}
      var o1={b:2}
      m.set(o,o1)//将对象o做为key,将对象o1做为值
      console.log(m)

      //对比对象
      var obj={}
      obj["a"]=1
      obj["fasle"]=2
      obj[o]=o1
      console.log(obj)

// 任何对象转换为字符串都会变为 [object Object]
      console.log(String(o))//[object Object]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方法

	var m = new Map()
      m.set("a", 1)
      m.set(false, 2)
      var o = { a: 1 }
      var o1 = { b: 2 }
      m.set(o, o1)
      //删除
      // m.delete("a")
      // m.clear()//清空m
      console.log(m.get(false))//2 根据键获取值
      console.log(m.get(o))//{b: 2}
      console.log(m.has("a"))//true  判断m中有没有键a
	  //map中存储键值对的个数
      console.log(m.size)//3

      console.log(m)

遍历m 中的键和值
m.forEach(function(value,key){
         console.log(value,key)
      })

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

遍历m中的值 返回为数组
	for(var item of m){
         console.log(item)
      }

	//使用解构 遍历出一个一个值
      for(var [key,value] of m){
         console.log(key,value)
      }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用keys()、values()、entries()
	//m.keys()获取到当前map中所有键的迭代器
      for(var key of m.keys()){
         console.log(key)
      }

      // //m.values()获取到当前map中所有值的迭代器
      for(var value of m.values()){
         console.log(value)
      }

      //m.entries() 将当前的map转换为迭代器
      for(var item of m.entries()){
         console.log(item)
      }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数组有同样的keys()、values()、entries()方法

	var arr=["a","b","c","d"];

      for(var item of arr){
          console.log(item)//a b c d
      }
      for(var index of arr.keys()){
          console.log(index)//0 1 2 3
      }
      for(var value of arr.values()){
          console.log(value)//a b c d
      }
      for(var value of arr.entries()){
          console.log(value)//[0,'a']
          				  // [1,'b']
          				  // [2,'c']
          				  // [3,'d']
      }

对象转换为Map

//对象转换为map时 需要先转换为一个二维数组
//将对象转换为一个迭代器,这个迭代器是一个二维数组,一个元素包括一个key和一个value
//使用Object.entries()转换为二维数组
	var obj = { a: 1, b: 2, c: 3 }
      var arr = Object.entries(obj)
      var m = new Map(arr)
      console.log(m)
//Map(3) {'a' => 1, 'b' => 2, 'c' => 3}

Map转换为对象

//使用Object.fromEntries()方法
var m = new Map()
      m.set("a", 1)
      m.set("b", 2)
      m.set("c", 3)
      m.set(true, 3)
      m.set({ a: 1 }, { b: 2 })
      console.log(m)
      var o=Object.fromEntries(m)
      console.log(o)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例 button点击

// 根据标签名获取到所有元素列表
      var bns = document.getElementsByTagName("button");
      var m = new Map()
      //迭代器转换为数组
      bns = Array.from(bns)
      for (var i = 0; i < bns.length; i++) {
         //第一行按钮添加了点击事件
         if (i == 0) bns[i].onclick = clickHandler;
         else {
            //其他的按钮变为不可用状态
            bns[i].disabled = true
            m.set(bns[i - 1], bns[i])
         }
      }
      function clickHandler() {
         //在点击事件中,this指向侦听当前点击事件的按钮
         //将当前点击的按钮不可用,然后取消当前点击的事件
         this.onclick = null
         this.disabled = true
         //如果在map中没有找到当前按钮对应的key,就跳出
         if (!m.has(this)) return
         //根据当前按钮的key找到下一个要点击的按钮
         //并且设置这个需要被点击的按钮的按钮事件和可用状态
         m.get(this).onclick = clickHandler;
         m.get(this).disabled = false
      }

WeakMap 弱引用类型

//WeakMap 的key只能是引用类型,并且不可遍历
      var m=new WeakMap()
      var o={a:1}
      var o1={a:2}
      m.set(o,o1)
      o=null;
      console.log(m)

symbol类型

// js的数据类型由简单类型和复杂类型组成  简单类型就是string、number、boolean 、undefined、null,复杂类型是object
// js的数据类型bigInt、number、string、boolean、function、undefined、object、symbol

// symbol不做任何元素,相当于一个标识,不管怎么创建Symbol,都不会产生重复的值
	 var a=Symbol();
      var b=Symbol();
      console.log(a==b);//false

去除魔术字符串

  const LEFT = Symbol(),
        RIGHT = Symbol(),
        TOP = Symbol(),
        BOTTOM = Symbol();
    const LEFT="left",RIGHT="right",TOP="top",BOTTOM="bottom"

    
      var state;
      state=LEFT
    // state ="left"
      switch (state) {
        case LEFT:
          console.log("left");
          break;
        case RIGHT:
          console.log("right");
          break;
        case TOP:
          console.log("top");
          break;
        case BOTTOM:
          console.log("bottom");
          break;
      }

注意点

将对象的key 设置为symbol可以防止被另外的属性覆盖

var s = Symbol("s")
      var abc = Symbol("abc")
      var obj = {
         a: 1,
         [abc]: 2,
         [s]: 3,
         s: 4,
         abc: 5
      }
      console.log(obj)//{a: 1, s: 4, abc: 5, Symbol(abc): 2, Symbol(s): 3}

for in 不会遍历Symbol属性

 for (var key in obj) {
         console.log(key)//只遍历出一个a
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值