美文网首页
ES6 新特性

ES6 新特性

作者: 渚清与沙白 | 来源:发表于2023-10-01 08:08 被阅读0次
    • let 和 const命令
    • es6模板字符串
    • 增强函数
    • 扩展的字符串、对象、数组功能
    • 解构赋值
    • Symbol
    • Map和Set
      ------------------------------------------------------------------
    • 迭代器和生成器
    • Promise对象
    • Proxy对象
    • async和await
    • 类了class
    • 模块化实现
    babel

    es6 转换 es5的工具

    let和const

    var变量会带来变量提升问题
    let没有变量提升,是一个块级作用域,其他块无法访问let声明的变量,不可重复声明
    const同 let 一样,另外,一旦声明不允许被修改。const声明的对象或数组,对象的属性,数组的元素可以修改

    字符串的扩展

    模板字符串${变量}

    反引号表示一个字符串,在反引号中使用模板字符串

    // 模板字符串使用方式
    let name = 'Kobe';
    let say = `您好,我是${name}`;
    
    字符串的遍历 for ... of ...
    let str = 'hello';
    for (const s of str) {
        console.log(s)
    }
    
    字符串新增方法

    includes()startWith()endWith()repeat()padStart()padEnd()trimStart()trimEnd()at()

    函数默认参数、剩余参数

    默认参数:给函数传参设置一个默认值。函数调用时,没有传递该值,则使用默认值。

    1. 带参数默认值的函数
    // 使用  options就设置了默认值,是一个空对象。传参时,可以不传递options
    const request = (method, url, data, options = {}) => {};
    
    1. 默认的表达式也可以是一个函数
    function add(a, b = getval(5)){
        return a + b;
    }
    function getval(v){
        return v + 1;
    }
    add(10);
    
    1. 剩余参数:由三个点...和一个紧跟着的具名参数指定 ...keys
      把多个参数值合并到一个数组,解决了arguments的问题。
    // 形参 是剩余参数
    funcation pick(...args){
    // 形参结果是一个数组
      console.log(args); // ['a','b','c']
    }
    // 实参 传递多个参数值
    pick('a','b','c')
    
    1. 展开运算符...
      扩展运算符将一个数组分割,并将各个项作为分离的参数传递给函数
    // 将对象defaultOpts的各个属性分割成独立的单项再设置给新的对象。
    uni.request({
         ...defaultOpts,
         success(response) {
                   
         },
    });
    

    *剩余参数主要放在函数形参上,扩展运算符主要在函数调用时传递实参

    箭头函数()=>{}

    用于替代函数表达式
    ()=>{}等价于function(){}
    只有一个参数,可以省略小括号;只有一行代码事,可以省略大括号
    es5中this指向取决于调用该函数的上下文对象
    箭头函数没有this指向,当前不存在作用域。内部this值只能通过查找作用域链来确定,往上一层作用域去查找

    const fn = (x)=>{
      console.log(x);
    }
    // 省略小括号
    const fn = x =>{
      console.log(x);
    }
    // 省略小括号和大括号
    const fn = x => console.log(x)
    // 只有一行省略 return
    const fn = x => x * x
    // 返回对象  代码块需要小括号包裹起来
    const fn = name => ({name})
    

    解构赋值

    是对赋值运算符的一种扩展
    针对数组和对象来进行操作

    对象解构赋值

    对象解构赋值是将对象的属性和方法快速批量赋值给一些列变量的简洁语法。
    接收参数方的变量名要与对象的属性名一致,但是变量名可改名。

    let person = {
      name: 'Li',
      age: 20
    }
    const name = 'A';
    // 解构改名
    const {name: username, age} = person;
    console.log(username);
    
    // 解构数组对象
    const [{name, age}] = [person],
    
    // 多级对象解构
    const person = {
      name: 'Z',
      student: {
        age: 16
      }
    }
    const {name, student: {age}} = person
    
    // 解构数组多级对象
    const person = [
      {
        name: 'Z',
        student: {
          age: 16
        }
      }
    ]
    const [{name, student: {age}}] = person
    
    // 解构传参
    const result = {
      code: 200,
      msg: '',
      data: [{id: 1},{id: 2},{id: 3}]
    }
    // 解构参数并修改名字
    function fn({data: myData}){
      console.log(myData);
    }
    fn(result);
    
    1. 完全解构
      将对象的属性全部解构出来
    // 变量 name和age要与person对象的属性保持一致
    let {name, age} = person;
    
    1. 不完全解构
      将对象的属性解构一部分
    //  需要name,只解构name即可,忽略其他
    let {name} = person;
    

    使用扩展运算符解构

    let obj = {
      a:{
        name: 'zs'
      },
      b: [],
      c: 'HW'
    }
    let {a, ...res} = obj;
    // 这里的res是会接收到一个对象,没有a属性的对象
    
    数组解构赋值

    数组解构赋值是将数组单元值快速批量赋值给一些列变量的简洁语法。

    let aar = [1,2,3];

    1. 完全解构
      let [a,b,c] = aar;
    2. 不完全解构
      let [a,b] = aar;
    3. 嵌套解构
      let [a,[b],c] = [1,[2],3];
    // 交换变量
    let a = 1;
    let b = 2; // 这里必须加分号
    const [b, a] = [a, b];
    
    // js前面必须加分号的情况
    // 立即执行函数
    (function fn (){ })();
    ;(function fn (){ })()
    // 数组解构
    ;[b, a] = [a, b]
    
    // 设置默认值
    const [a = 0, b = 0] = [b, a]
    
    // 按需导入赋值
    const [a, b, , d] = [1,2,3,4]
    
    // 剩余参数
    const [a, b, ...c] = [1,2,3,4]
    
    // 多维数组解构
    const [a, b, [c, d]] = [1,2,[3,4]]
    

    对象的扩展功能

    1. 属性简洁表示法
      es6支持直接写入属性和函数,作为对象的属性方法返回值
    // es6写法
    const person = {
      name,
      age,
      say(){}
    }
    // es5写法
    const person = {
      name:name,
      age:age,
      say:function(){}
    }
    
    1. 属性名表达式[]
      对象取值或调用方法支持表达式
    // 第一种
    const person = {};
    const name = 'z';
    const fun = 's';
    person[name+'c'] = '张三';
    person[fun+'ay'] = function(){}
    
    person对象最终结果
    {'zs':'张三','say':f}
    
    // 第二种
    const name = 'z';
    const person = {
      [name+'s']:‘张三’,
      [fun+'sy'](){}
    };
    
    1. 对象支持is和assign方法
      is类似===,比较两个是否严格相等
      ===中不是完全严格比较,有个特例NaN,is就解决了NaN的问题
    console.log(NaN === NaN);
     结果:false
    console.log(Object.is(NaN,NaN));
     结果:true
    

    assign:对象的合并
    用法:Object.assign(target,obj1,obj2...)

    let person = Object.assign({},{name:'zs'},{age:10})
    结果:{name:'zs',age:10}
    

    Symbol

    Symbol是原始数据类型,它表示独一无二的值
    用途:用来定义对象的私有变量

    赋值与取值[]

    let name = Symbol('name');
    let person = {};
    // 变量name作为了person对象的私有变量,并赋值
    person[s1] = ‘张三’;
    // 取值必须用```[]```
    const nameValue = person[s1];
    

    Set集合

    特点:无重复、有序
    属性:size,entries
    创建:new
    添加:add
    删除:delete
    校验是否存在集合中:has
    set转换成数组:扩展运算符方式
    let arr = [...set2]
    set中对象的引用无法被释放
    解决方式:调整创建方式,不直接new Set,而是使用WeakSet弱引用
    WeakSet

    • 不能传入非对象类型的参数
    • 不可迭代
    • 没有forEach
    • 没有size属性

    Map

    特点:有序、键值是任意类型
    创建:new Map
    map.set
    map.has
    map.delete
    map.clear

    数组的扩展

    • from与of方法
    1. from()
      将伪数组转换为真正的数组
      伪数组
      伪数组类似数组,都可通过数组的方式去读取数据arr[0],只能使用length属性,不能使用数组的函数。伪数组可以通过from函数转换成真正的数组
      arguments
    function add(){
        console.log(arguments);
        // result [1,2,3,4,5]
    }
    add(1,2,3,4,5);
    

    ② 元素集合
    let titles = document.querySelectorAll("h3"); titles也是一个伪数组
    ③ 伪数组的对象

    let user = {
        "0":"A",
        "1":30,
        "2":true,
        length:3
    }
    

    通过扩展函数from可将伪数组转换为真正的数组,具备数组的一些方法,如push等。

    let arr = Array.from(arguments);
    // 也可以用扩展运算
    let arr = [...arguments];
    
    1. of() 将任意类型的一组数据,转换成数组类型
    let arr = Array.of(1,2,3,4,5);
    // result [1,2,3,4,5]
    
    • copywithin()方法
      从数组的指定位置拷贝元素到数组的另一个指定位置中
      语法:array.copyWithin(target, start, end)
    • find()和findIndex()
      查找元素
    迭代器Iterator

    Iterator是一种新的遍历机制
    两个核心
    是一个接口,能快捷地访问数据,通过Symbol创建迭代器,通过next()函数获取迭代之后的结果
    迭代器是用于遍历数据结构的一个指针或游标
    使用迭代

    const items = [1,2,3];
    // 通过Symbol创建新的迭代器
    const ite = items[Symbol.iterator]();
    // next函数结果 {value:1,done:false}  
    // done为false表示遍历继续,为true表示遍历完成
    ite.next(); 
    
    generator生成器

    generator函数 可以通过yield关键字,将函数挂起,为了改变执行流提供了可能性。同时为了做异步编程提供了可能。
    与普通函数的区别

    1. function后面 函数名之前有个*
    2. 只能在函数内部使用yield表达式,让函数挂起,表达式必须与yield在一行书写,否则不会执行
    • 基本用法
    function* fn(params){
      console.log('start');
      yield 2;
      console.log('center');
      yield 3;
      console.log('end');
    }
    let res = fn();
    console.log(res.next());
    console.log(res.next());
    console.log(res.next());
    
    结果
    start
    {value:2,done:false} 
    center
    {value:3,done:false} 
    end
    {value:undefined,done:true} 
    

    总结:generator函数是分段执行的,yield语句是暂停执行,next()函数是恢复执行

    • next()传值
    function* add(){
        console.log('start');
        // x 可真的不是yield ‘2’的返回值,它是next()调用 恢复当前的yield()
        let x = yield '2';
        console.log('one:' + x);
        let y = yield '3';
        console.log('two:' + y);
        return x + y;
    }
    const fn = add();
    console.log(fn.next()); // { value: '2',done: false }
    console.log(fn.next(20));// { value: '3',done: false }
    console.log(fn.next(30));// { value: '50',done: true }
    
    • generator的应用
    function* main(){
        console.log('main')
        let res = yield request('https://free-api.heweather.net/s6/weather/now')
        console.log(res)
        // 执行后面的操作
        console.log('数据请求完成,可以继续操作')
    }
    
    const ite = main();
    ite.next();
    function request(url){
        $.ajax({
            url,
            method: 'get',
            success(res){
                ite.next(res);
            }
        })
    }
    

    Promise 承诺

    promise是异步编程的一种解决方案,它是一个对象。
    特点

    1. 对象的状态不受外界影响,处理异步操作三个状态
      Pending 进行中
      Resolved 成功
      Rejected 失败
    2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果

    创建promise

    let pro = new Promise(function(resolved,rejected){
      // 异步操作
      resolved(data);
      rejected(err);
    });
    // 异步结果
    pro.then((res)=>{
      // 成功
    },(err)=>{
      // 异常
    });
    

    其他方法
    resolve():将现有的任何对象转换成Promise对象

    let p = Promise.resolve('abc');
    等价于
    let p = new Promise(resolve=>resolve('abc'))
    

    all():异步并行操作

    let pro1 = new Promise((resolve,reject)=>{});
    let pro2 = new Promise((resolve,reject)=>{});
    let p = Promise.all([pro1,pro2]);
    p.then(res=>{
      // res是一个数组
      // 三个成功  才算成功
    }).catch(err=>{
      // 只有失败一个  所以的promise对象都失败
    });
    

    race():某个异步请求设置超时时间,并且超时后执行相应的操作

    Promise.race([pro1,timeout]);
    

    done():不管成功与失败都会执行
    finally():不管成功与失败都会执行

    async异步操作

    作用:使得异步操作更加方便
    async是Generator的一个语法糖
    async会返回一个promise对象
    如果async函数中有多个await,then函数会等等所有的await指令运行完才会执行

    async function fn(){
      return await '';
    }
    fn().then(res=>{})
    
    
    async function fn(){
        let str = await 'hello world';
        let data = await str.split(' ');
        return data;
    }
    fn().then(v => console.log(v)).catch(e => console.log(e))
    
    

    await关键字只能在async修饰的代码块中使用,await 后面都是跟着的一个promise对象,如不不是,他会自动转换成promise对象。

    Generator、Promise、async/await 解决回调地狱问题,使得异步更加方便

    class类

    ES5造类

    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    Person.prototype.sayNmae = function() {
        return this.name;
    }
    let p1 = new Person('Tom',24);
    console.log(p1);
    

    ES6造类

    class Person {
        // 构造函数 实例化时会立即被调用
        constructor(name,age) {
            this.name = name;
            this.age = age;
        }
        sayNmae() {
            return this.name;
        }
        sayAge() {
            return this.age;
        }
    }
    let p2 = new Person('Tom',24);
    // 通过Object.assign()函数一次性仿类中添加多个方法
    Object.assign(Person.prototype,{
        sayNmae() {
            return this.name;
        },
        sayAge() {
            return this.age;
        }
    })
    
    • 类的继承
    class Worker extends Person {
        constructor(name,age,sex){
            super(name,age);
            this.sex = sex;
        }
        // 子类自己的方法
        saySex() {
            return `${this.name}已经${this.age}岁,他的性别是${this.sex}`;
        }
        // 重写父类方法
        sayNmae() {
            return `我的名字是:${this.name}`;
        }
    }
    const w = new Worker('渚清与沙白',14,'男生');
    

    如何让多个类混入到一个类?

    模块实例化exportimport

    export用于规定模块的对外接口

    • 分别暴露
      export const user = {}
    • 统一暴露
      const user = {};
      const people = {};
      export { user , people}
    • 默认暴露
      const user = {};
      export default user;

    import用于输入其他模块提供的功能

    • 导入静态资源:import ... from ...
    // 导出
    export const name = 'Tom';
    export function sayNmae(){
        return '渚清与沙白';
    }
    
    // 导入
    <script>
        import { name } from "./test.js";
    </script>
    
    • 动态导入:import('')
      动态导入的魔法注释
    //魔法注释 webpack中的预获取  网页加载完毕,网络空闲时才去获取数据
    import(/* webpackPrefetch: true */ './path/to/LoginModal.js');
    //魔法注释 webpack中的预加载
    import(/* webpackPreload: true */ 'ChartingLibrary');
    {
      path: '/list/:id',
      name: 'list',
      component: () => import(/* webpackChunkName: "list-index" */ '@/views/list/index.vue'),
      meta: {
          hasFoot: true,
      },
    },
    

    命名
    default 一个文件只能使用一次

    export const name = 'Kebo';
    const obj = {};
    export default obj;
    
    // 抛出部分  解构
    import { name } from '';
    // 抛出所有
    import * as f from '';
    

    相关文章

      网友评论

          本文标题:ES6 新特性

          本文链接:https://www.haomeiwen.com/subject/yjsrbdtx.html