05-ES6

发布于:2025-07-24 ⋅ 阅读:(19) ⋅ 点赞:(0)

数据解构

Set

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

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

  //set集合,成员是唯一的,添加过程中会替换相同的元素。这里相同的标准是===
  const s = new Set();
  s.add(1);
  s.add("2");
  s.add(3);
  s.add(4).add(5);
  console.log(s); //{ 1, '2', 3, 4, 5 }
  /***************==和===的区别****************************** */
  var a = 1;
  var b = "1";
  console.log(a == b); //true,只比较值,不比较类型
  console.log(a === b); //false,值和类型都比较

  //set类型的删除,返回的是一个bool值
  s.delete(1);
  console.log(s);
  //清除所有的成员
  s.clear();
  //判断是否存在
  s.has(2);
  //获取成员数量
  s.size();
  //与数组结构类型转换
  const set = new Set([1, 2, 3, 4, 5, 6]); //Array-->Set
  let arr = Array.from(set); //Set-->Array
  //扩展运算符
  let arr2 = [...set];
  console.log(arr2);
  //并集、交集、差集
  const list1 = [1, 2, 3, 4, 5];
  const list2 = [2, 4, 5];

  var listall = list1.concat(list2);
  const set1 = new Set(listall);
  console.log([...set1]); //并集
  const set2 = [...new Set([...list1, ...list2])]; //并集
  var listjiao = list1.filter((v) => list2.includes(v));
  console.log(listjiao); //交集

  var listchaji = list1.filter((v) => !list2.includes(v));
  console.log(listchaji); //差集

Map

JavaScript 的对象(Object),本质上是键值对的集合,但是传统上只能用字符串当作键。这给它的使 用带来了很大的限制

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类 型的值(包括对象)都可以当作键

  const m1 = new Map();
  m1.set("id", 1).set("name", "jack");
  //console.log(m1); //Map { 'id' => 1, 'name' => 'jack' }

  //定义其他类型,任何类型都可以作为键
  let arr = [1, 2, 3];
  m1.set(arr, 100);
  console.log(m1); //Map { 'id' => 1, 'name' => 'jack', [ 1, 2, 3 ] => 100 }

  //map长度
  console.log(m1.size);
  //通过键获取数据
  console.log(m1.get("id"));

  //has(key) 返回一个布尔值,表示某个键是否在当前 Map 对象之中
  console.log(m1.has("id"));
  
  //delete(key) 删除某个键,返回 true 。如果删除失败,返回 false
  console.log(m1.delete("id"));
  
  //clear() 清除所有成员,没有返回值
  m1.clear();

  //map的循环遍历---使用for...of进行循环遍历

  //另一种定义方式,二维数组
  const m2 = new Map([
    ["a", 1],
    ["b", 2],
    ["c", 3],
  ]);
  console.log(m2); //Map { 'a' => 1, 'b' => 2, 'c' => 3 }

for..of循环

for...of 循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments 对 象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串

能够使用for...of循环的对象内部需要有Symbol方法

普通对象不能使用for...of进行循环

  const arr = ["red", "green", "gray"];
  for (let v of arr) {
    console.log(v); //输出数组内的元素
  }
  const s = new Set(arr);
  for (let v of s) {
    console.log(v); //"red", "green", "gray"
  }

  for (let [i, v] of arr.entries()) {
    console.log(i); //索引
    console.log(v); //元素
  }

  const m1 = new Map();
  m1.set("id", 1).set("name", "jack");
  for (let v of m1) {
    console.log(v); //[ 'id', 1 ] [ 'name', 'jack' ]
  }
  //数组解构
  for (let [k, v] of m1) {
    console.log(k); //键
    console.log(v); //值
  }
  //普通对象使用for...of
  var o1 = { id: 1, name: "jack" };
  for (let v of o1) {
    console.log(v); //异常:TypeError: o1 is not iterable
  }
  //解决方法
  var o2 = { id: 1, name: "jack" };
  for (let v of Object.entries(o2)) {
    console.log(v); //数组结构,[ 'id', 1 ]
  }
  for (let [k, v] of Object.entries(o2)) {
    console.log(k);
    console.log(v);
  }

for...of与其它遍历的比较

/*********************各种for循环的比较***************************** */
  //1、最原始的写法就是for循环
  var arr1 = [1, 2, 3, 4, 5];
  for (var i = 0; i < arr1.length; i++) {
    console.log(arr1[i]);
  }
  //2、forEach方法:这种写法的问题在于,无法中途跳出forEach循环,break命令或return命令都不能奏效
  arr1.forEach(function (item, index) {
    console.log(item);
  });
  //3、for...in
  for (let i in arr) {
    console.log(i); // 0 1 2 3 4获取索引
    console.log(arr[i]);
  }
  for (let i in arr) {
    if (i == 3) {
      break;
    }
    console.log(i); //0 1 2 索引
  }

  //4、for...of
  const arr2 = ["a", "b", "c", "d", "e"];
  for (let v of arr2) {
    if (v == 3) {
      break; //用于跳出循环,会继续执行该循环之后的代码(如果有的话)
      //continue; //如果指定了条件,中断当前的迭代,然后继续循环中的下一个迭代。
    }
    console.log(v); //输出的是元素
  }

各种类型的转换

  //1、对象转换为数组
  const o1 = { id: 1, name: "jack" };
  Object.keys(o1); //['id','name']
  Object.values(o1); //[1,'jack']
  console.log(Object.entries(o1)); //[ [ 'id', 1 ], [ 'name', 'jack' ] ]

  //2、map转换为数组
  const m1 = new Map();
  m1.set("a", 1).set("b", 2).set("c", 3);
  console.log([...m1.keys()]); //[ 'a', 'b', 'c' ]
  console.log([...m1.values()]); //[ 1, 2, 3 ]
  console.log(...m1); //[ 'a', 1 ] [ 'b', 2 ] [ 'c', 3 ]
  console.log(...m1.entries());

  for (let v of m1.entries()) {
    console.log(v);
  }
  for (let v of [...m1]) {
    console.log(v);
  }

  //3、对象转为map
  var o2 = { id: 1, value: "v" };
  let m2 = new Map(Object.entries(o2));

  //4、map转对象
  const o3 = {};
  for (let [k, v] of m2) {
    console.log(v);
    o3[k] = v;
  }
  console.log(o3);

symbol数据结构

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值

解决问题:如果添加的属性名出现重复,如何保证属性名的唯一性,解决属性名的冲突

  let s = Symbol();
  let s1 = Symbol("a"); //这的参数a是描述symbol,通过描述可以区分不同的symbol

  /****************************************** */
  const o1 = {};
  o1.id = 10;
  o1.id = 20;
  //正常情况下,id=10将会被id=20覆盖掉
  //如果想不被覆盖掉???
  var id = Symbol("id1"); //id1是symbol的描述
  o1[id] = 30;
  var id = Symbol("id2"); //id2是symbol的描述
  o1[id] = 40;
  console.log(o1); //{ id: 20, [Symbol(id1)]: 30, [Symbol(id2)]: 40 }

  //第二种定义方式
  var id = Symbol("id");
  let o2 = { id: 10, [id]: 20 };
  console.log(o2); //{ id: 10, [Symbol(id)]: 20 }
  //获取id的值
  console.log(o2.id); //返回默认的属性值10
  console.log(o2[id]); //20 通过[id]的方式获取symbol的属性值。o2[id]:这的id对应的是变量

  //symbol即使描述相同,symbol()的返回值也不相同
  let s3 = Symbol("ITI");
  let s4 = Symbol("ITI");
  s3 === s4; // false
  
  //Symbol属性值的获取
  const o3 = { id: 10, [Symbol("id1")]: 20, [Symbol("id2")]: 30 };
  console.log(o3[Object.getOwnPropertySymbols(o3)[0]]);//20
  console.log(o3[Object.getOwnPropertySymbols(o3)[1]]);//30

注意symbol作为对象属性名,不能用扩展运算符进行解析

使用symbol作用属性名,Object.keys(),for...in不能输出symbol类型的属性名

Symbol.for()

由于symbol()每次调用都会返回一个不同的值,如果希望重新使用同一个Symbol 值, Symbol.for() 方法可以做到这一点

  let s5 = Symbol.for("ITI");

  let s6 = Symbol.for("ITI");

  console.log(s5 === s6);//true

Symbol.for()与Symbol()的区别

Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。区别是,前者会被登记在全局环境中供搜 索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key 是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30 次,每次都会返回 同一个 Symbol 值,但是调用Symbol("cat")`30 次,会返回 30 个不同的 Symbol 值

Promise

所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API, 各种异步操作都可以用同样的方法进行处理.

  //promise是一个构造函数,可以通过new Promise()得到一个promise实例
  //Promise构造函数接受一个函数作为参数--相当于传一个回调。这个函数有两个参数,分别是:resolve和reject
  //resolve和reject是两个函数。这两个函数是由JS引擎提供的
  //promise有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)
  //resolve的作用是:是将promise的状态从进行中变成成功
  //reject的作用是:将promise的状态从进行中转换为rejected
  //then方法:当promise实例一旦生成了
  let p = new Promise(function (resolve, reject) {
    if (异步操作成功) {
      resolve("ok");
    } else {
      reject("error");
    }
  });
  //通过p的then方法能够获取promise内部的异步操作的状态
  //then方法存在于Promise的prototype原型对象上
  p.then(
    function (res) { 
      console.log(res); //ok
    },
    function (err) {
      console.log(err); //error
    }
  );

  /*******************图片加载实例******************************* */
  function LoadImg() {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = function () {
        resolve(img);
      };
      img.onerror = function () {
        reject("error");
      };
    });
  }
  LoadImg().then(
    (res) => {},
    (error) => {}
  );

Promise---all

Promise.all() 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例

 /*******************promise.all():并发任务只有全部成功才会执行then方法******************** */
  let p2 = new Promise((resolve, reject) => {
    console.log("第一个异步任务");
    resolve("第一次异步结果");
  });
  let p3 = new Promise((resolve, reject) => {
    console.log("第二个异步任务");
    resolve("第二次异步结果");
  });
  let p4 = new Promise((resolve, reject) => {
    console.log("第三个异步任务");
    resolve("第三次异步结果");
  });
  Promise.all([p2, p3, p4]).then((arr) => {
    console.log(arr); //[ '第一次异步结果', '第二次异步结果', '第三次异步结果' ]
  });

  /************并发任务执行:这几个任务都会执行,
   * 但是如果其中一个出现reject,则最后都不会执行Promise.all的then方法,而是执行Promise.all的catch方法
   * **************** */
  let p5 = new Promise((resolve, reject) => {
    console.log("第一个异步任务");
    resolve("第一次异步结果");
  });
  let p6 = new Promise((resolve, reject) => {
    console.log("第二个异步任务");
    reject("第二次异步结果失败");
  });
  let p7 = new Promise((resolve, reject) => {
    console.log("第三个异步任务");
    resolve("第三次异步结果");
  });
  Promise.all([p5, p6, p7])
    .then((arr) => {
      console.log(arr);
    })
    .catch((err) => {
      console.log(err); //第二次异步结果失败
    });

Promise---race

const p = Promise.race([p1, p2, p3]);

只要 p1 、 p2 、 p3 之中有一个实例率先改变状态, p 的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数

  /***************promise.race():获取到的是最先执行异步任务的成功状态的返回值********************** */
  let p8 = new Promise((resolve, reject) => {
    console.log("第一个异步任务");
    setTimeout(() => {
      resolve("第一次异步结果");
    }, 3000);
  });
  let p9 = new Promise((resolve, reject) => {
    console.log("第二个异步任务");
    setTimeout(() => {
      resolve("第二次异步结果");
    }, 2000);
  });
  let p10 = new Promise((resolve, reject) => {
    console.log("第三个异步任务");
    setTimeout(() => {
      resolve("第三次异步结果");
    }, 5000);
  });
  Promise.race([p8, p9, p10]).then((res) => {
    console.log(res); //第二次异步结果
  });

 /** 如果p9出现异常,则不会进行promise.race的then方法,而是需要promise.race设置一个catch方法*/

async-await

async function f () {
   return 'hello world'
}
f(); //为什么没有执行'hello world'

//执行f

f().then((res) => console.log(res));

函数前面加上async,如果执行这个函数,这个函数返回一个promise实例。相当于生成promise实例的简单方法。

async修饰的function,默认是成功的状态。return 'hello world'相当于resolve的返回值

await操作符用于等待一个Promise对象,它只能在异步函数async function内部使用

await 后面跟一个promise对象,但是也可以跟其他值,比如字符串、数值、普通函数

  console.log(1);
  async function f2() {
    console.log(2);
    await 100;//执行等待,后面的代码变成微任务
    console.log(3);
  }
  f2();
  console.log(4);

//整个代码输出:1 2 4 3

网站公告

今日签到

点亮在社区的每一天
去签到