ES6新特性

81 阅读10分钟

ES6新特性

目录

[TOC]

let 声明变量

不能重复声明,块级作用域(if else for while) ,不存在变量提升,不影响作用域链

  //不能重复声明,
    // let start = 1
    // let start = 2
 
    // 块级作用域
    // {
    //     let age = 18
    // }
    // console.log(age);
 
    // 不存在变量提升
    // console.log(a);
    // let a = 1
 
    // 不影响作用域链
    // {
    //     let age = 18
    //     function fn() {
    //         console.log(age);
    //     }
    //     fn()
    // }

const声明常量

必须有初始值,常量的值不能修改,块级作用域,操作空间地址不算重新赋值

 
    // 必须有初始值
    // const age = 18
 
    // 常量的值不能修改
    // age = 8
 
    // 块级作用域
    // {
    //     const age = 18
    // }
    // console.log(age);
 
    // 操作空间地址不算重新赋值
    // const arr = [1, 2, 3]
    // arr.push(4)

解构赋值

允许按照一定格式从数组和对象中提取值,对变量进行赋值

    // 数组的解构
    // let f4 = ['小沈阳', '刘能', '赵四', '宋小宝']
    // let [x, l, z, s] = f4
    // console.log(x, l, z, s);
 
    // 对象解构
    // let zhao = {
    //     name: '赵本山',
    //     age: '60',
    //     xiaopin: function () {
    //         console.log('我可以演小品');
    //     }
    // }
    // let { xiaopin } = zhao
    // xiaopin()

模板字符串

可以识别换行符,拼接变量

    let age = 18
    let str = `我今年${age}了`
    console.log(str);

对象的简化写法

kv 一致省略v 函数可以不写function

    let age = 18
    let name = 'jyc'
    let obj = {
        name,
        age,
        fn() {
            console.log(obj.age);
        }
    }
    obj.fn()

箭头函数

  • 没有自己的this,this指向函数声明时所在作用域下this的值
  • 不能作为构造函数
  • 不能使用arguments
  • 形参就一个值可以省略小括号,执行语句就一个值可以省略花括号和return
    // var age = 18
    // let obj = {
    //     age: 22
    // }
    // function getAge() {
    //     console.log(this.age);
    // }
    // let getAge1 = () => {
    //     console.log(this.age);
    // }
    // getAge()
    // getAge1()
    // getAge.call(obj)
    // getAge1.call(obj)
 
 
    // let fn = a => a + a
    // console.log(fn(1));

函数参数的默认值设置

允许函数参数赋初始值

   function add(a, b, c = 10) {
        return a + b + c
    }
    // console.log(add(1, 2));
 
 
    //与解构赋值结合
    function reqire({ host, userName, password, port = 8080 }) {
        console.log(host);
        console.log(userName);
        console.log(password);
        console.log(port);
    }
    reqire({
        host: ' 172.168.0.0.1',
        userName: 'root',
        password: 'root',
 
    })

rest参数

用于获取函数实参代替arguments

 
    // arguments es5伪数组
    // function data() {
    //     console.log(arguments);
    // }
 
 
    // rest参数必须要放到最后得到数组
    function data(a, b, ...args) {
        console.log(args);
    }
    data('小白', '小明', '小李', 1, 2, 3)//(4) ['小李', 1, 2, 3]

扩展运算符

合并 浅克隆 伪数组转数组

    //合并
    let a = [1, 2, 3]
    let b = [4, 5, 6]
    let arr = [...a, ...b]
    console.log(arr);
 
    //浅克隆
    let arr2 = [...arr]
    console.log(arr2);
 
    // 伪数组转数组
    function fn() {
        console.log([...arguments]);
    }
    fn('小白', '小明', '小李')

symbol

es6引入了一种新的原始值类型symbol,表示独一无二的值,

symbol是唯一的,用来解决命名冲突的问题,不能参与运算,不能使用for in 使用refice,ownkeys

主要用于给对象添加属性和方法

创建使用

    let game = {
        name: '俄罗斯方块',
        up: () => { },
        down: () => { }
    }
    let methods = {
        up: Symbol(),
        down: Symbol(),
    }
    game[methods.up] = function () {
        console.log('我可以改变形状');
    }
    game[methods.down] = function () {
        console.log('我可以下降');
    }
    console.log(game);

Symbol.hasInstance

当其对象用 instanceof,判断是否为该对象的实例时会调用这个方法

    class Person {
        static [Symbol.hasInstance]() {
            console.log('我被用来检测类型');
            return true
        }
    }
    let o = {}
    console.log(o instanceof Person); //true

Symbol.isConcatSpreadable

等于的是一个布尔值,表示Array.prototype.content()时是否可以展开

    let arr1 = [1, 2, 3]
    let arr2 = [4, 5, 6]
    arr1[Symbol.isConcatSpreadable] = false
    let arr = arr1.concat(arr2)
    console.log(arr);//(4) [Array(3), 4, 5, 6]

迭代器 iterator

迭代器是一种接口 ,为各种不同的数据结构,提供统一的访问机制,任何数据结构只要部署了iterator接口就可以完成遍历操作

es6创造了一种新的遍历命令 for...of..  iterator接口主要提供 for...of..消费

具备iterator接口的数据 array ,arguments,set map string typeArray NodeList

工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置,
  • 第一次调用对象的.next方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用.next方法,指针一直往后移动,直到指向最后一个成员
  • 每次调用next方法,返回一个包含value和done属性的对象
    let arr = [10, 20, 30]
 
    let iterator = arr[Symbol.iterator]()//一个函数 得到一个对象 
    console.log(iterator);//得到一个对象 ,有一个next方法(指针)
    console.log(iterator.next());//包含一个value 和done属性的对象
    console.log(iterator.next())
    console.log(iterator.next())
    console.log(iterator.next())// {value: undefined, done: true}done表示完成状态

自定义遍历数据

    const banji = {
        name: '终极一班',
        stus: [
            'zs',
            'ls',
            'ww',
            'xm'
        ],
        [Symbol.iterator]() {
            let index = 0
            let self = this
            return {
                next: function () {
                    if (index < self.stus.length) {
                        const result = { value: self.stus[index], done: false }
                        index++
                        return result
                    } else {
                        return { value: undefined, done: true }
                    }
                }
            }
        }
    }
    for (const val of banji) {
        console.log(val);
    }

生成器 generator

生成器其实是一个特殊的函数 可以解决异步编程

可以使用 yield 语句 函数代码的分割符

创建和使用

    function* gen() {
        console.log(11);
        yield '一只没有耳朵'
        console.log(22);
        yield '一只没有尾巴'
        console.log(33);
        yield '真奇怪'
        console.log(44);
    }
    let iterator = gen()
    console.log(iterator);// 返回迭代器对象
    iterator.next()//控制生成器函数执行
    iterator.next()
    iterator.next()
    iterator.next()

参数的传递

next函数传递的参数当做上一次 yield 的语句的返回结果

    function* gen(args) {
        console.log(args);
        let one = yield 11
        console.log(one);
        let two = yield 22
        console.log(two);
        let three = yield 33
        console.log(three);
    }
    let iterator = gen('aa')
 
    iterator.next('bb')
    iterator.next('cc')
    iterator.next('dd')
    iterator.next()

案例

模拟获取 用户数据 订单数据 商品数据

    function getUsers() {
        setTimeout(() => {
            let data = '用户数据'
            //第二次调用next的 将数据传入 当做第一个yield的语句的返回结果
            iterator.next(data)
        }, 1000);
    }
    function getOrders() {
        setTimeout(() => {
            let data = '订单数据'
            iterator.next(data)
        }, 1000);
    }
    function getGoods() {
        setTimeout(() => {
            let data = '商品数据'
            iterator.next(data)
        }, 1000);
    }
    function* gen() {
        let user = yield getUsers()
        console.log(user);
        let Orders = yield getOrders()
        console.log(Orders);
        let Goods = yield getGoods()
        console.log(Goods);
    }
    let iterator = gen()
    iterator.next()

promise

promise是一个构造函数用来封装异步操作,并可以获取成功或者失败的结果

promise构造函数 promise(excutor)

promise.prototype.then    promise.prototype.catach

基本使用

 
    let p = new Promise(function (resolve, reject) {
        setTimeout(() => {
            // let data = '用户数据'
            // resolve(data)
            reject(new Error('失败'))
        }, 1000);
    })
    p.then((res) => {
        console.log(res);
    }).catch((err) => {
        console.log(err);
    })
 

then方法

  • 调用then方法返回的是promise 状态由回调函数执行结果决定,
  • 如果回调函数是非promise类型的属性,转态是成功,返回值是为成功值
  • 是一个promise promise状态决定了.then的状态
  • 抛出错误为失败的promise
 let p = new Promise(function (resolve, reject) {
        setTimeout(() => {
            let data = '用户数据'
            resolve(data)
            // reject(new Error('失败'))
        }, 1000);
    })
    let result = p.then((res) => {
        console.log(res);
        return new Promise((resolve, reject) => {
            resolve('ok')
        })
    }, err => {
        console.log(err);
    })
    //调用then方法返回的是promise 状态由回调函数执行结果决定,
    // 如果回调函数是非promise类型的属性,转态是成功,返回值是为成功值
    // 是一个promise promise状态决定了.then的状态
    //抛出错误为失败的promise
    console.log(result);
    result.then((res) => {
        console.log(res);
    })
    // 链式调用
    p.then(res => {
 
    }).then(res => { 
 
    })

catch

捕捉失败的promise

    let p = new Promise(function (resolve, reject) {
        setTimeout(() => {
 
            reject(new Error('失败'))
        }, 1000);
    })
    p.catch(err => {
        console.log(err);
    })

set

set数据结构,他类似于数组,但成员的值是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和for..of遍历结合的属性和方法

  • size 返回集合元素的个数
  • add 增加一个元素返回当前集合
  • delete 删除元素,返回布尔值
  • has 检测集合中包含某个元素,返回布尔值、
  • clear 清空集合
   let s = new Set([1, '1'])
    // 元素的个数
    console.log(s.size)
    // 添加元素
    s.add(2)
    console.log(s);
    //删除元素
    s.delete(2)
    console.log(s);
    // 检测
    console.log(s.has(1));
    // 清空
    // s.clear()
    // console.log(s);
 
    for (const val of s) {
        console.log(val);
    }

应用

let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
    // 去重
    // let result = [...new Set(arr)]
    // console.log(result);
    //交集
    let arr2 = [4, 5, 6]
    // let result = [...new Set(arr)].filter(item => new Set(arr2).has(item))
    // console.log(result);
    // 并集
    // let result = [...new Set([...arr, ...arr2])]
    // console.log(result);
    //差集
    let result = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
    console.log(result);

map

他类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对偶)都可以作为键 也实现了iterator接口 可以使用for..of 和扩展运算符

  • size返回map元素个数
  • set 增加一个新元素 返回放前map
  • ger 返回健名对象的键值,
  • has 检测集合中包含某个元素,返回布尔值、
  • clear 清空集合
 
 
    let map = new Map()
    // 添加元素
    map.set('name', 'zs')
    map.set('change', function () {
        console.log(111);
    })
    let key = {
        love: '爱好'
    }
    map.set(key, ['唱', '跳', 'rap'])
    console.log(map);
    // 个数
    console.log(map.size);
    // 删除
    // map.delete('name')
    // console.log(map);
    // 获取
    // console.log(map.get('change')());
    // 清空
    // map.clear()
    // console.log(map);
    //遍历
    for (const v of map) {
        console.log(v);
    }

class

  • class声明类
  • constructor定义构造函数初始化
  • exends继承父类
  • super调用父级构造方法
  • static定义静态方法和属性

es5

    function Phone(brand, price) {
        // 实例属性
        this.brand = brand
        this.price = price
    }
    // 静态属性方法
    Phone.name = '手机'
    Phone.change = function () {
        console.log('我可以改变事件');
    }
    //实例方法
    Phone.prototype.call = function () {
        console.log('我可以打电话');
    }
    //子类属性继承(改变this指向)
    function SmartPhone(brand, price, color, size) {
        Phone.call(this, brand, price)
        this.color = color
        this.size = size
    }
    // 修改子类原型继承父类方法
    SmartPhone.prototype = new Phone
    // constructor 指回子类
    SmartPhone.prototype.constructor = SmartPhone
    SmartPhone.prototype.playGame = function () {
        console.log('我可以打游戏');
    }
    let huawei = new SmartPhone('华为', 2999, '白色', 5)
    huawei.call()
    console.log(huawei);

es6

 class Phone1 {
        constructor(brand, price) {
            // 实例属性
            this.brand = brand
            this.price = price
        }
        // //实例方法
        call() {
            console.log('我可以打电话');
        }
        // 静态属性属性方法
        static name = '手机'
        static change() {
            console.log('我可以改变事件');
        }
    }
    //extends 继承
    class SmartPhone1 extends Phone1 {
        constructor(brand, price, color, size) {
            //调用父类的构造器完成属性继承
            super(brand, price)
            this.color = color
            this.size = size
        }
        playGame() {
            console.log('我可以打游戏');
        }
        //重写父类方法
        call() {
            console.log('我可以视频通话');
        }
        // 获取劫持
        get say() {
            console.log('我被读取了');
            return 11
        }
        //设置劫持
        set say(newVal) {
            console.log('我被修改了' + newVal);
        }
    }
    let huawei = new SmartPhone1('华为', 2999, '黑色', 5)
    huawei.call()
    console.log(huawei);
    huawei.say = 99
    console.log(huawei.say);

数值扩展

  • Number.EPSILON 最小精度
  • 二进制 八进制
  • Number.isFinite 检测一个值是否为有限小数
  • Number.isNaN 是否为NaN
  • Number.parseInt  parseFloat 字符串转整数
  • Number.isInteger 判断是否为整数
  • Math.trunc 将小数部分抹除掉
  • Math.sign 判读一个数字为正数负数还是0
    // Number.EPSILON 最小精度
    function equal(a, b) {
        if (Math.abs(a - b) < Number.EPSILON) {
            return true
        } else {
            return false
        }
        console.log(equal(0.1 + 0.2, 0.3));
    }
    // 二进制 八进制
    let b = 0b1010
    console.log(b);
    // Number.isFinite 检测一个值是否为有限小数
    console.log(Number.isFinite(100 / 0));
    // Number.isNaN 是否为NaN
    console.log(Number.isNaN('99'));
    // Number.parseInt 字符串转整数
    console.log(Number.parseInt('255efqxx'));
    console.log(Number.parseFloat('3.14efwefw'));
    // Number.isInteger 判断是否为整数
    console.log(Number.isInteger(44.4));
    // Math.trunc 将小数部分抹除掉
    console.log(Math.trunc(23.14));
    // Math.sign 判读一个数字为正数负数还是0
    console.log(Math.sign(-99));
 

对象扩展方法

  • // Object.is 判断两个值是否完全相等
  • // Object.assign 对象的合并
  • // Object.setPrototypeOf 设置原型对象
  • // Object.getPrototypeOf  获取原型对象
    // Object.is 判断两个值是否完全相等
    console.log(Object.is(NaN, NaN));
    console.log(Object.is(120, 121));
    // Object.assign 对象的合并
    let statu = {
        name: 'zs',
        age: 18
    }
    let statu2 = {
        name: 'ls',
        age: 22,
        sex: '男'
    }
    let res = Object.assign(statu, statu2)
    console.log(res);
    // Object.setPrototypeOf 设置原型对象
    // Object.getPrototypeOf  获取原型对象
    let arr = [11]
    let obj = {
        a: 10
    }
    console.log(Object.setPrototypeOf(obj, arr));
    console.log(Object.getPrototypeOf(obj));

模块化

模块化是一个大的程序文件,拆分成许多个小的文件 然后把小文件合起来

防止命名冲突,代码复用,高维护性

  • CommonJS----》nodejs
  • Amd---》requireJS
  • cmd--》seaJS

ES6模块化语法

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

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

暴露

export 分别暴露

export{} 统一暴露

export defult{} 默认暴露

导入

通用导入方式

import * as from ‘xxx’

解构赋值

import{a,b}from 'xxx' 如果是默认暴露import {defult as data}from‘xxx’(因为默认暴露的是一个对象 使用别名的形式)

针对默认暴露的简便写法

import data from‘xxx’

es7新特性

includes 数组方法 是否含有某一项 返回布尔值

**运算等同于 Math.pow

    let arr = [1, 2, 3]
    let res = arr.includes(4)
    console.log(res);
    //**
    console.log(2 ** 10);

async await

解决异步编程

async

  • async返回一个promise对象
  • promis对象的结果有async函数执行的返回值决定
  • (返回的不是一个promise对象,返回的成功的promise,抛出异常返回失败的promise)(如果返回的是一个promise 由这个promise的状态决定)
    async function fn() {
        // return 1
        // new Error('失败')
        return new Promise((reslove, reject) => {
            // return reslove(11)
            reject('失败')
        })
    }
    let res = fn()
    res.then((result) => {
        console.log(result);
    }).catch((err) => {
        console.warn(err);
    });

await

  • await必须写在async函数里
  • await右边表达式一般为promise
  • await返回的是promise成功的值
  • await的promise失败了,需要通过try catch捕获
    let p = new Promise((reslove, reject) => {
        return reslove(11)
        // reject('失败')
    })
    async function fn() {
        try {
            let result = await p
            console.log(result);
        } catch (e) {
            console.warn(e);
        }
    }
    fn()

es8对象扩展方法

Object.keys(obj) 获取对象的所有键

(Object.values(obj) 获取对象的所有值

Object.entries(obj) 方法返回一个给定对象自身可枚举属性的键值对数组。快速创建map结构

Object.getOwnPropertyDescriptors(obj1)获取对象的描述对象(是否可写,枚举,删除)

    let obj = {
        name: 'zs',
        age: 18
    }
    //args:原型对象 描述对象
    let obj1 = Object.create(null, {
        name: {
            value: 'zs',
            writable: true,
            configurable: true,
            enumerable: true
        }
    })
 
    //获取对象的所有键
    console.log(Object.keys(obj));
    // 获取对象的所有值
    console.log(Object.values(obj));
    // 方法返回一个给定对象自身可枚举属性的键值对数组。快速创建map结构
    console.log(new Map(Object.entries(obj)));
    //获取对象的描述对象(是否可写,枚举,删除)
    console.log(Object.getOwnPropertyDescriptors(obj1));

es9扩展运算符&&rest参数对对象的操作

    function fn({ age, sex, ...user }) {
        console.log(age);
        console.log(sex);
        console.log(user);
    }
    fn({
        age: 18,
        sex: '男',
        name: 'zs',
        job: '前端'
    })
    let age = { age: 18 }
    let sex = { sex: '男', }
    let name = { name: 'zs' }
    let job = { job: '前端' }
    let user = { ...age, ...sex, ...job, ...name }
    console.log(user);

es10对象扩展方法fromEntries

fromEntries:将二维数组,map转为对象

Object.entries对象转为二维数组

 
    const result = Object.fromEntries([
        ['name', 'lise'],
        ['job', '前端']
    ])
    const map = new Map()
    map.set('name', 'zs')
    const res = Object.fromEntries(map)
    console.log(result);
    console.log(res);
    let data = Object.entries({
        name: 'ww'
    })
    console.log(data);

es10字符串扩展方法

trimStart左侧空格

trimEnd右侧空格

    let str = ' love  '
    console.log(str);
    console.log(str.trimStart());
    console.log(str.trimEnd());

es10数组扩展方法

flat数组将维

flatMap数组循环将维

    let arr = [1, 2, 3, [4, 5, 6]]
    let res = arr.flat()
    console.log(res);
    let result = res.flatMap(item => [item * 10])
    console.log(result);

description获取Symbol字符串

 
    let w = Symbol('ls')
    console.log(w.description);

Promise.公有方法

Promise.allSettled promise 的状态始终是成功  保存着每一个promise的状态

Promise.all 有一个失败promise的状态就为失败

    let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('成功')
        }, 1000);
    })
    let p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('失败')
        }, 1000);
    })
    let res = Promise.allSettled([p1, p2])
    let result = Promise.all([p1, p2])
    console.log(res);
    console.log(result);

可选链操作符

    function fn(args) {
        const res = args?.obj?.a
        console.log(res);
    }
    fn({
        b: 10,
        // obj: {
        //     a: 1
        // }
    })

BigInt大整数

    let max = Number.MAX_SAFE_INTEGER
    console.log(max);
    console.log(max + 1);
    console.log(max + 2);
    console.log(max + 8);
    console.log(BigInt(max) + BigInt(10));

globalThis绝对全局对象