ES6兼用性

虽然我用的电脑都能兼容es6的语法,凡是有些人的电脑真是老古董,浏览器不知道是多少年的版本了。如果不靠第三方转换es5语法,就硬写es6的语法,可能有些浏览器不兼容。

查看es6的兼容性

01. let/const

声明变量/常量的关键字。用来代替var。

let

  1. 不允许重复声明;
  2. 块儿级作用域(局部变量);
  3. 不存在变量提升;

    就是在声明变量之前就使用变量,var可以,但let不行

  4. 不影响作用域链;

    子块里面可以访问父块的let

  1. // let关键字使用示例:
  2. let a; // 单个声明
  3. let b,c,d; // 批量声明
  4. let e = 100; // 单个声明并赋值
  5. let f = 521, g = 'iloveyou', h = []; // 批量声明并赋值

const

  1. 声明必须赋初始值;
  2. 标识符一般为大写(习惯);
  3. 不允许重复声明;
  4. 值不允许修改;
  5. 块儿级作用域(局部变量);
  6. 如果常量是一个数组或者对象,不能修改这个数组或者对象,但是能修改这个数组或者对象内部的值

    02. 解构赋值

    ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值

    数组解构

    代码说明
    1. const F4 = ["苹果","梨子","香蕉","西瓜"];
    2. let [a,b,c,d]=F4; //这样赋值abcd就和上面的数组里面的数值一一对应
    3. console.log(a);
    4. console.log(b);
    5. console.log(c);
    6. console.log(d);
    运行结果
    image.png

    对象解构

    代码说明
    ```javascript const A ={ name:”张三”, age:23, score:[100,98,56,34], method:function(){
    1. console.log("A的方法");
    } }

let {name,age,score,method} =A;//必须与对象属性名相同 console.log(name); console.log(age); console.log(score); console.log(method);

  1. <a name="JEFVm"></a>
  2. ##### 运行结果
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21464164/1620550770414-6f03445a-8e0b-45e3-b403-4a145181bef7.png#clientId=u3c6d26ed-33d6-4&from=paste&height=144&id=u771a7ea5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=144&originWidth=252&originalType=binary&size=3026&status=done&style=none&taskId=u20a1da7c-787c-4124-9fc5-4ad1299f1b4&width=252)
  4. <a name="lpnBg"></a>
  5. # 03. 模板字符串
  6. 模板字符串(template string)是增强版的字符串,用反引号(`)标识,在键盘tab键上面<br />特点:
  7. -
  8. 字符串中可以出现换行符;
  9. - 可以使用 **${xxx}** 形式引用变量,进行字符串拼接;
  10. <a name="fk58N"></a>
  11. ##### 代码说明
  12. ```javascript
  13. let html =`
  14. <div>
  15. <p>哈哈哈</p>
  16. </div>`;

字符串拼接

代码说明
  1. let abc="这是一个字符串";
  2. let html2 =`
  3. <div>
  4. <p>${abc}</p>
  5. </div>`;
  6. console.log(html2);

运行结果

image.png

04. 简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;

代码说明
  1. let name ="张三";
  2. let eat =function(){
  3. console.log("吃饭");
  4. };
  5. let score=[20,30,54]
  6. //es6简便的写法
  7. let A ={
  8. name,
  9. eat,
  10. score
  11. }
  12. //等同于这种写法
  13. let B={
  14. name:name,
  15. eat:eat,
  16. score:score
  17. }
  18. console.log(A);
  19. console.log(B);

运行结果

image.png

05. 箭头函数

ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿 名函数的定义

代码说明
  1. let a =function(){
  2. //这是es5声明匿名函数并且赋值的写方法
  3. };
  4. let b = (q,w)=>{
  5. return q+w;
  6. //es6中的箭头函数,省略了function关键字
  7. //括号里面同样写形参
  8. };
  9. //调用函数,名字加参数
  10. console.log(b(1,2));

注意

  1. 如果形参只有一个,则小括号可以省略;
  2. 函数体如果只有一条语句,则花括号可以省略,不用写return,函数的返回值为该条语句的执行结果;
  3. 箭头函数 this 指向声明时所在作用域下 this 的值;
  4. 箭头函数不能作为构造函数实例化;
  5. 不能使用 arguments,用来获取函数的实参;
    代码说明
    ```javascript //箭头函数如果只有一个参数,小括号可以省略 let aa = name =>{ return “这是名字:”+name; } console.log(aa(“张三”));

//箭头函数如果只有一条语句,花括号也可以省略,不用写return,函数的返回值就是这条语句的 执行结果 let bb = name => “这是新名字:”+name; console.log(bb(“李四”));

//箭头函数不能使用arguments let a =function(){ console.log(arguments); }; a();//可以使用

let b =()=> console.log(arguments); b();

  1. <a name="iUj4B"></a>
  2. ##### 运行结果
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21464164/1620553706891-403cb7b1-6792-4906-8792-70de3a00c25c.png#clientId=u3c6d26ed-33d6-4&from=paste&height=151&id=uccce8849&margin=%5Bobject%20Object%5D&name=image.png&originHeight=151&originWidth=409&originalType=binary&size=6449&status=done&style=none&taskId=u5c174da0-6b80-4a64-a8e0-6a796360c69&width=409)
  4. <a name="GnQht"></a>
  5. # 06. 参数赋值初始值
  6. <a name="o8aq7"></a>
  7. ##### 代码说明
  8. ```javascript
  9. let a = (q,w,e) => console.log(q+w+e);
  10. a(1,2,3);//能正常执行
  11. a(1,2);//少一个参数就是报错
  12. a = (q,w,e=10) => console.log(q+w+e); //一般设有初始值的参数都放在后面
  13. a(1,2);//不填第三个参数就使用默认值10,填了第三个参数就使用填写的参数

运行结果

image.png

07. 剩余参数

剩余参数和 arguments对象之间的区别主要有三个:

  • 剩余参数…args 只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
  • arguments对象不是一个真正的数组,而剩余参数是真正的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop。
  • arguments对象还有一些附加的属性 (如callee属性)
    代码说明
    ```javascript let a= function(){ console.log(arguments); } a(“张三”,”李四”,”赵柳”);

//形参写上 …args ,写在最后一个参数 let b=(…args)=>{ console.log(args); //拿到的是一个数组 } b(“哈哈哈”,”呵呵呵”,”嘿嘿嘿”,”嘻嘻嘻”);

let c=(q,w,…args)=>{ console.log(“q:”+q); console.log(“w:”+w); console.log(“args:”+args); } c(“哈哈哈”,”呵呵呵”,”嘿嘿嘿”,”嘻嘻嘻”)

  1. <a name="pnfXl"></a>
  2. ##### 运行结果
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21464164/1620555239394-ea32bbb2-4628-43d9-904f-457757068761.png#clientId=u3c6d26ed-33d6-4&from=paste&height=129&id=ufc36f94a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=129&originWidth=562&originalType=binary&size=5842&status=done&style=none&taskId=uf3442ad5-8dc7-4ead-a556-47f13f10656&width=562)
  4. <a name="ytYce"></a>
  5. # 08. 扩展运算符[...]
  6. <a name="sCfFu"></a>
  7. ##### 代码说明
  8. ```javascript
  9. const A=["张三","李四","王五","赵柳"];
  10. const B=["西瓜","苹果","桃子","榴莲"];
  11. //合并数组
  12. const C=[...A,...B];
  13. console.log(C);
  14. //克隆数组,这个不是引用A的内存地址了
  15. const D=[...A];
  16. console.log(D);
  17. //把伪数组转换成数组
  18. let a =new Set([1,2,3,4]);//声明一个set集合
  19. let arr=[...a];//把集合转换成数组
  20. console.log(arr);

运行结果

image.png

09. 迭代器

原生具备 iterator 接口的数据(可用 for of 遍历):

  • Array;
  • Arguments;
  • Set;
  • Map;
  • String;
  • TypedArray;
  • NodeList;
    代码说明
    ```javascript const A=[“张三”,”李四”,”王五”,”赵柳”];

//for of遍历数组里面的内容 for(let item of A){ console.log(item); }

//for in遍历数组里面的索引 for(let index in A){ console.log(index); }

  1. <a name="M5oca"></a>
  2. ##### 运行结果
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21464164/1620557830671-30a7d8ee-b690-401e-8338-7aa9f96f244b.png#clientId=u3c6d26ed-33d6-4&from=paste&height=183&id=uca7d1e1e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=183&originWidth=252&originalType=binary&size=2478&status=done&style=none&taskId=u6058b7c7-4071-4202-881e-50bc2689cb4&width=252)
  4. <a name="Yed6B"></a>
  5. # 10. 生成器
  6. 可以这么理解,可以暂停的函数。执行到一部分,突然不想执行了,停一下,过一会又想继续执行那个函数,还可以接着执行。
  7. yield相当于函数的分隔符,把函数分成一段一段的,调用一次执行一段,再调用一次同样的方法,会执行第二段,以此迭代,直到调用完最后一段。<br />3个yield把函数分成4段。
  8. <a name="WG6Q5"></a>
  9. ##### 代码实现
  10. ```javascript
  11. function * gen() {
  12. //这是第一段
  13. //yield好比结尾符号,我在中间部分不写,写在yield限定符的后面,也属于第一段的范围。
  14. yield console.log("打印的第一段内容");
  15. //这是第二段
  16. console.log("打印的第二段内容");
  17. yield '名字'
  18. //这是第三段
  19. console.log("打印的第三段内容");
  20. yield
  21. //这是第四段
  22. console.log("打印的第四段内容");
  23. }
  24. let iterator = gen();
  25. //每执行一个next方法,就会执行函数中的一段,会迭代执行,直到用next执行完
  26. iterator.next();
  27. //第二次调用next方法,就执行第二段
  28. console.log(iterator.next()); //第二段,只有写字符串,才有value值
  29. console.log(iterator.next());//第三段,yield后面不写,打印出来没有value
  30. iterator.next(); //这是执行第四段
  31. console.log("遍历");
  32. for(let i of gen()){
  33. //执行函数里面的每一段代码,打印全部yield的值,如果yield后面没有写字符串,是没有值的
  34. console.log(i);
  35. }

运行结果

image.png

使用案例

这么一个需求,调用方法后,一秒钟后打印111,又过两秒钟后打印222,又过三秒钟后打印333

代码说明

这样解决了回调地狱的问题,一层套一层,套多了,缩进很让人头疼

  1. function one(){
  2. setTimeout(()=>{
  3. console.log(111);
  4. a.next();
  5. },1000)
  6. }
  7. function two(){
  8. setTimeout(()=>{
  9. console.log(222);
  10. a.next();
  11. },2000)
  12. }
  13. function three(){
  14. setTimeout(()=>{
  15. console.log(333);
  16. },3000)
  17. }
  18. function * gen(){
  19. one();
  20. yield '第一段结尾'
  21. two();
  22. yield '第二段结尾'
  23. three();
  24. }
  25. let a=gen();
  26. a.next();

next传参案例

next方法可以传参数,第二次调用next方法传入的参数会作为第一个yield的返回结果。以此类推。

代码实现
  1. function one(){
  2. setTimeout(()=>{
  3. let data="111111111111";
  4. a.next(data);
  5. },1000)
  6. }
  7. function two(){
  8. setTimeout(()=>{
  9. let data="22222222222";
  10. a.next(data);
  11. },2000)
  12. }
  13. function three(){
  14. setTimeout(()=>{
  15. let data="3333333333333333333";
  16. a.next(data);
  17. },3000)
  18. }
  19. function * gen(){
  20. one();
  21. let a=yield
  22. console.log(a);
  23. two();
  24. let b= yield
  25. console.log(b);
  26. three();
  27. let c=yield
  28. console.log(c);
  29. }
  30. let a=gen();
  31. a.next();

运行结果

image.png

11.Promse

语法上 Promise 是一个构造函数,用来封装异步操作 并可以获取其成功或失败的结果;

代码说明
//实例化Promise对象
//Promise的参数是一个函数,而且这个函数有两个形参,连个参数名字随便写
const p = new Promise((resolve,reject)=>{
    setTimeout(() => {
        let data="经过了5秒成功了";
        let data2="经过5秒失败了";
        //完成了一些列操作过后,可以调用Promise的两个参数函数,来改变p的状态
        //p有3个状态,初始化,成功,失败

        //调用第一个参数函数,p对象的状态就会变为成功
        resolve(data);
        //调用第二个参数函数,p对象的状态就会变成失败
        reject(data2);
        //两个都写只有第一个生效
    }, 5000);
})

//调用promise对象的then方法
//then方法接受两个参数,两个函数,而且每个函数都有一个形参
//p的状态为成功,就会回调一个函数,p的状态为失败,就会回调第二个函数
p.then((value)=>{
    console.log(value);
},(error)=>{
    console.error(error);
})

执行异步事件

传输数据,打开文件,写入文件等都需要一定的事件,如果一个事情就要花费3-5秒,几件事同步执行就要花几十秒。异步就是让他们一起执行,最短的一件事需要3秒,最长的一件事需要7秒,那么所有事件完成的时间就是7秒。

代码说明

//定义了三个异步事件,都需要一定事件完成,让他们同时执行,节约时间
const p = new Promise((resolve,reject)=>{
    setTimeout(() => {
        let data="经过了5秒成功了";
        resolve(data);
    }, 5000);
})

const p2 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        let data="经过了3秒失败了";
        reject(data);
    }, 3000);
})

const p3 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        let data="经过了6秒成功了";
        resolve(data);
    }, 6000);
})

p.then((value)=>{
    console.log(value);
},(error)=>{
    console.error(error);
});
p2.then((value)=>{
    console.log(value);
},(error)=>{
    console.error(error);
});
p3.then((value)=>{
    console.log(value);
},(error)=>{
    console.error(error);
})

运行结果

只花了6秒全部时间都完成了
image.png

then的返回结果

then方法的返回结果也是一个Promise对象,但是这个对象的状态由then方法执行结果决定。

p.then(),如果p的状态的成功的,then方法返回的promise对象状态就是成功,反之就是失败。但是这样没有返回的值。
then方法里面也可以写return new Promise,这个新的promise对象的状态决定then方法的返回状态。

这样就可以进行链式编程p.then().then().then(),这么写可读性差。

12. set集合

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:

代码说明
//声明set
let s=new Set();
console.log(s,typeof s);

//可以传入一个可迭代输入
let a=['香蕉','西瓜','苹果','西瓜'];
let ss=new Set(a);//会自动去重
console.log(ss,typeof ss);

//元素的个数
console.log(ss.size);
//添加新元素
ss.add('哈密瓜');
console.log(ss,typeof ss);
//删除元素
ss.delete('哈密瓜');
//检查集合里面有没有这个元素
console.log(ss.has("香蕉"));
//清空集合
ss.clear();
console.log(ss);

运行结果

image.png

13. Map

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类 型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和
『for…of…』进行遍历;
Map就像升级的对象,字典一样


//声明map
let a=new Map();

//添加元素
a.set('name','张三');
a.set('m',()=>console.log('哈哈哈'));

//获取元素个数
console.log(a.size);

//获取
console.log(a.get('m'));

//清空
a.clear();

14. Class

class Phone{
  // 构造方法,名字是固定的
  constructor(brand,price) {
  this.brand = brand;
  this.price = price;
  }
  // 打电话,方法必须使用该方式写
  call(){
  console.log("我可以打电话!");
  }
}
let HuaWei = new Phone("华为",5999);
HuaWei.call();
console.log(HuaWei);