关于es6新特性的总结

42 篇文章 0 订阅

1.let & const

  1. let,作用与var类似,用于声明变量

特性:

  1. let 不能重复声明变量,var 可以重复声明变量;
  2. 块级作用域,es5中存在全局作用域、函数作用域、eval作用域;es6中引入了块级作用域,let声明的变量在块级作用域{}内有效
  3. let声明的变量不存在var的变量提升问题

举个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="container">
        <h2 class="page-header">点击切换颜色</h2>
        <div class="item">1</div>
        <hr>
        <div class="item">2</div>
        <hr>
        <div class="item">3</div>
    </div>

    <script>
        // 获取div对象
        let items = document.getElementsByClassName('item')

        // 遍历并绑定事件 遍历时let i
        for(let i = 0; i < items.length; i++){
            items[i].onclick = function(){
                items[i].style.background = 'pink'
            }
        }
        /*
        相当于在3个块级作用域内分别声明了i
        {
            let i = 0
            items[i].onclick = function(){
                items[i].style.background = 'pink'
            }
        }
        {
            let i = 1
            items[i].onclick = function(){
                items[i].style.background = 'pink'
            }
        }
        {
            let i = 2
            items[i].onclick = function(){
                items[i].style.background = 'pink'
            }
        }
        */

        /*
        // 遍历并绑定事件 遍历时var i
        for(var i = 0; i < items.length; i++){
            items[i].onclick = function(){
                // 修改当前元素的背景颜色
                this.style.background = 'pink' // 此处this指向’被绑定的元素对象‘,即调用该函数的对象
                // 此处不能和上文一样使用 items[i].style.background = 'pink',
                // 因为var的i不考虑块级作用域, 则相当于在全局声明了一个变量,循环结束后i=3,
                // 函数执行时向上层寻找最终得到全局变量i=3,而items[3]为undefined
            }
        }
        相当于
        {
            var i = 0
            // ...

        }
        {
            var i = 1
            // ...
        }
        {
            var i = 2
            // ...
        }
        {
            var i = 3
        }

        */
    </script>
</body>

<style>
    .item{
        width: 200px;
        height: 50px;
        border-radius: 2%;
        background-color: brown;
    }
</style>

</html>
  1. const 用于声明常量

注意事项:

  1. 一定要赋初始值
  2. 一般常量使用大写(属于编程规范)
  3. 常量值不能修改
  4. 存在块级作用域
  5. 对于数组和对象的元素修改,不算做对常量的修改,不会报错(因为引用数据类型保存的是内存地址,所以声明数组和对象时可以使用const声明,以此保证其保存的内存地址不变)

2.解构赋值

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

  1. 数组的解构

        const Web = ['html', 'css', 'javascript']
        let [tool1, tool2, tool3] = Web

        console.log('tool1-----', tool1) // html
        console.log('tool2-----', tool2) // css
        console.log('tool3-----', tool3) // javascript
  1. 对象的解构

        const liMing = {
            name: 'liMing',
            age: '22',
            tell: function(){
                console.log(`I am liMing`)
            }
        }

        let {name, age, tell} = liMing

        console.log(name) // 'liMing'
        console.log(age) // '22'
        console.log(tell) // f(){...}
        tell() // I am liMing

3.模板字符串

特性:

  1. ` `(反引号)内容中可以直接出现换行符,’ '和" "中则不可以,出现会报错
  2. 可以直接进行变量拼接

4.简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法(在属性名和变量名相同的情况下),这样的书写更加简洁

        let name = 'LiMing'
        let tell = function(){
            console.log('I am LiMing')
        }

        const liMing = {
            name,
            tell,
            sayHi(){
                console.log('hello')
            }
        }

        // 等效于
        // const liMing = {
        //     name: name,
        //     tell: tell,
        //     sayHi: function(){
        //         console.log('hello')
        //     }
        // }

        console.log(liMing)
        liMing.tell()
        liMing.sayHi()

5.箭头函数

与function声明的区别:

  1. 箭头函数this是静态的。

    • 箭头函数内的this指向上层对象;始终指向函数声明时所在作用域下的this的值,无法被call改变

    • 普通函数内的this指向调用其函数的对象

      function getName(){
          console.log(this.name)
      }
      
      let getName2 = ()=>{
          console.log(this.name)
      }
      
      // 设置window对象的name属性
      window.student = 'LiMing'
      const student = {
          name: 'HanMei'
      }
      
      // 直接调用
      getName() // LiMing
      getName2() // LiMing
      
      // call方法调用
      getName.call(student) // HanMei
      getName2.call(student) // LiMing
      
  2. 箭头函数不能作为构造函数实例化对象

        let Person = (name, age)=>{
            this.name = name
            this.age = age
        }
        let me = new Person('LiMing', 20) // 报错:Uncaught TypeError: Person is not a constructor
    
  3. 箭头函数不能使用arguments变量,但是可以使用....rest

        let fn = ()=>{
            console.log(arguments)
        }
    
        fn(1, 2, 3) // 报错:Uncaught ReferenceError: arguments is not defined
        
    
        let fn2 = (...rest)=>{
            console.log(...rest)
        }
    
        fn2('a','b','c') // a b c
    
  4. 箭头函数的简写
    ① 当形参有且只有一个的时候,可以省略()
    ② 当代码体只有一条语句的时候,可以省略{},此时return必须省略,而且语句的执行结果就是函数的返回值

        // 当形参有且只有一个的时候,可以省略`()`
        let add = n => {
            return n + n
        }
    
        console.log(add(9))
    
        // 当代码体只有一条语句的时候,可以省略`{}`,此时`return`必须省略,而且语句的执行结果就是函数的返回值
        let pow = n => n*n
    
        console.log(pow(9))
    

5.箭头函数的例子
箭头函数适合与this无关的回调,比如定时器setTimeout(()=>{...}, 2000)、数组的方法回调arr.filter((item)=>{...})
不适合与this有关的回调,比如dom元素的事件回调ad.addEventListener('click', function(){...}、对象内的方法定义{name: 'LiMing', getName: function(){this.name}}
例1:

        // 需求-1 点击div 2s后颜色变红
        
        // 获取元素
        let ad = document.getElementById('ad')
        // 绑定事件
        ad.addEventListener('click', function(){
            setTimeout(function(){
                console.log(this) // 定时器里的this指向window
                this.style.background = 'brown' // 报错
            }, 2000)
        })

        //解决方案1
        // ad.addEventListener('click', function(){
        //     // 保存this的值
        //     let _this = this // _this指向ad
        //     setTimeout(function(){
        //         console.log(_this) 
        //         _this.style.background = 'brown'
        //     }, 2000)
        // })

        // 解决方案2
        // ad.addEventListener('click', function(){
        //     setTimeout(()=>{
        //         console.log(this) 
        //         this.style.background = 'brown' // this指向函数声明时所在作用域下this的值 即ad
        //     }, 2000)
        // })

例2:

        // 需求-2 从数组中返回偶数的元素
        const arr = [1, 6, 9, 10, 100, 25]
        const result = arr.filter(function(item){
            if(item %2 === 0){
                return true
            }else{
                return false
            }
        })

        // 可以用箭头函数
        // const result = arr.filter(item => {
        //     if(item % 2 === 0){
        //         return true
        //     }else{
        //         return false
        //     }
        // })
        // 还可以简写为
        // const result = arr.filter(item => item % 2 === 0)

        console.log(result)

6.函数参数的默认值设置

ES6允许给函数参数赋初始值

        function add(a, b, c=10){ // 具有默认值的参数,一般位置要靠后
            return a + b + c
        }
        console.log(add(1,2,))

可以与解构赋值一起使用

        function connect({host='127.0.0.1', port, username, password}){
            console.log(host, port)
            console.log(username, password)
        }
        
        connect({
            port: 3306,
            username: 'root',
            password: 'root',
        })

7.rest参数

ES6引入rest参数,用于获取函数的实参,用来代替arguments

        // ES5获取实参的方式
        function printStudent(){
            console.log(arguments) // arguments为一个对象
        }
        printStudent('LiMing','HanMeimei')

        // ES6获取实参的方式
        function printFriend(friend1, friend2, ...rest){ // rest参数必须放在形参列表最后,否则会报错
            console.log(friend1) 
            console.log(friend2) 
            console.log(rest) // 得到一个数组,可以使用数组api
        }
        printFriend('小猫','小狗','兔子','鸭子')
        // 小猫
        // 小狗
        // ['兔子','鸭子']

8.扩展运算符

...能将「数组」转为逗号分隔的「参数序列」
注:虽然形式与rest参数类似,但是rest参数是用在函数定义时的形参位置,扩展运算符是用在函数实际调用时的实参位置

        const STUDENTS = ['小明','小芳','小红']
        function printStudent(){
            console.log(arguments)
        }

        printStudent(STUDENTS) // 参数为一个数组,数组内包含3个元素
        printStudent(...STUDENTS) // 参数为3个元素

应用场景:

  1. 数组的合并

        const STUDENTS1 = ['小明','小芳','小红']
        const STUDENTS2 = ['小吴', '小王']
    
        // es5写法
        const STUDENTS_ES5 = STUDENTS1.concat(STUDENTS2)
        // es6写法
        const STUDENTS_ES6 = [...STUDENTS1, ...STUDENTS2]
    
        console.log('es5------',STUDENTS_ES5)
        console.log('es6------',STUDENTS_ES6)
    
  2. 数组的克隆

        const STUDENTS1 = ['小明','小芳','小红']
    
        const PUPIL = [...STUDENTS1] // 注意:如果数组内元素是引用类型,拷贝的是内存地址,为浅拷贝
        console.log('PUPIL----',PUPIL)
    
  3. 将伪数组转为真正的数组

        const divs = document.querySelectorAll('div')
        console.log(divs) // 此处得到的divs实际是一个对象
    
        const divsArr = [...divs] // 将其转为真正的数组,从而可以使用数组的api譬如filter、map
        console.log(divsArr)
    

9.Symbol

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第7种数据类型,是一个类似字符串的数据类型

Symbol特点:

  1. Symbol的值是唯一的,用来解决命名冲突的问题
  2. Symbol值不能与其他数据进行运算,也不能与自己进行运算,譬如+、-、*、/、比较运算
  3. Symbol定义的对象属性不能使用for…in遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名

创建Symbol:

  1. 通过let s2 = Symbol('张三') 的方式创建Symbol,'张三’作为Symbol描述,作用相当于注释,这种方式创建的Symbol,即使传入的描述一致,但实际返回的值是不同的

        // 创建Symbol
        let s = Symbol()
        console.log(s,typeof s) // Symbol() "symbol"
    
        let s2 = Symbol('张三') // '张三'作为Symbol描述,作用相当于注释
        let s3 = Symbol('张三') // 即使传入的描述一致,但实际返回的值是不同的
        console.log(s2 === s3) // false
    
  2. 通过Symbol.for()创建Symbol,这种方式创建Symbol,传入的描述一致,实际返回的值也一致,可以得到唯一的Symbol值

        // Symbol.for创建Symbol
        let s4 = Symbol.for('张三')
        let s5 = Symbol.for('张三')
        console.log(s4 === s5) // true
    

Symbol使用场景

  1. 给对象添加属性和方法。由于Symbol值具有唯一性,所以可以很安全地把属性和方法加入对象中,如下所示

        let game = {
            up: 'upp',
            down: 'doown'
        }
    
        let methods = {
            up: Symbol(),
            down: Symbol(),
        }
    
        // 添加方法
        game[methods.up] = function(){
            console.log('up up up')
        }
        game[methods.down] = function(){
            console.log('down down down')
        }
    
        console.log('game----', game)
        // 调用
        game[methods.up]()
    
    
        let youxi = {
            name: '狼人杀',
            [Symbol('say')]: function(){ // 此处不能直接写 Symbol('say'): function(){...},因为Symbol('say')是动态的,和上面固定的'name'不一样
                console.log('发言')
            }
        }
    

Symbol内置值

ES6除了定义自己使用的Symbol值以外,还提供了11个内置的Symbol值,指向语言内部使用的方法,比如

  1. Symbol.hasInstance
    当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法

        class Person{
            static [Symbol.hasInstance](param){
                console.log('param----', param)
                console.log('检测类型')
            }
        }
    
        let o = {}
    
        console.log(o instanceof Person)
        // param---- {}
        // 检测类型
        // false
    
  2. Symbol.isConcatSpreadable
    对象的Symbol.isConcatSpreadable属性等于一个bool值,表示该对象用于Array.prototype()时,是否可以展开

        const arr1 = [1,2,3]
        const arr2 = [4,5,6]
        arr2[Symbol.isConcatSpreadable] = false // arr2不可展开
        const arr = arr1.concat(arr2)
        console.log(arr) // [1,2,3,[4,5,6]]
    
  3. Symbol.unscopables
    该对象指定了使用with关键字时,哪些属性会被with环境排除

  4. Symbol.match
    当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值

  5. Symbol.replace
    当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值

  6. Symbol.search
    当该对象被str.search(myObject)方法调用时,会返回该方法的返回值

  7. Symbol.split
    当该对象被str.split(myObject)方法调用时,会返回该方法的返回值

  8. Symbol.iterator
    对象进行for ... of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器

  9. Symbol.toPrimitive
    该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值

  10. Symbol.toStringTag
    在该对象上调用toString方法时,返回该方法的返回值

  11. Symbol.species
    创建衍生对象时,会使用该属性

10.迭代器

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

ES6创造了一种新的遍历命令for...of循环,iterator接口主要供for...of消费
注:for...of遍历的是键值,for...in遍历的是键名
for...of不能对属性值进行修改,forEach()可以

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

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList

工作原理:

  1. 创建一个指针对象,指向当前数据结构的起始位置

  2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员

  3. 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员

  4. 每调用next方法返回一个包含value和done属性的对象,done属性表示遍历是否结束

        const food = ['鱼香肉丝','糖醋里脊','酸菜鱼']
        for(let item of food){
            console.log(item)
        }
    
        let iterator = food[Symbol.iterator]()
    
        console.log(iterator.next()) // {value: "鱼香肉丝", done: false}
        console.log(iterator.next()) // {value: "糖醋里脊", done: false}
        console.log(iterator.next()) // {value: "酸菜鱼", done: false}
        console.log(iterator.next()) // {value: undefined, done: true} true 表示遍历已经结束
    

注:需要自定义遍历数据的时候,要想到迭代器

迭代器应用-自定义遍历数据(即自己手动实现一个迭代器)

        // 声明一个对象
        const school = {
            name: '三中',
            students: [
                'LiMing',
                'HanMeimei',
                'WangFang',
            ],
            [Symbol.iterator](){
                // 声明一个索引变量
                let index = 0
                return {
                    next: ()=>{
                        if(index < this.students.length){
                        // if(index < 3){
                            const result = {value: this.students[index], done: false}
                            // 下标自增
                            index++
                            // 返回结果
                            return result
                        }else{
                            return {value: undefined, done: true}
                        }
                    }
                }
            }
        }

        // 遍历这个对象
        for(let item of school){
            console.log(item)
        }

11.生成器

生成器本身是一个特殊的函数,生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同

  • 执行生成器函数,返回的是一个迭代器对象,通过iterator.next()调用执行函数内语句

        function * gen(){
            console.log('hello generator')
        }
        let iterator = gen() // 返回的是一个迭代器对象
        // console.log(iterator)
        // 通过.next()调用执行函数内语句
        iterator.next() // hello generator
    
  • yield是函数代码的分隔符,结合调用iterator.next()方法,实现函数gen1的语句的分段执行

        function * gen1(){
            console.log('--- 1 ---')
            yield '耳朵' // 函数代码的分隔符
            console.log('--- 2 ---')
            yield '尾巴'
            console.log('--- 3 ---')
        }
    
        let iterator1 = gen1()
        iterator1.next() // --- 1 ---
        iterator1.next() // --- 2 ---
        iterator1.next() // --- 3 ---
        // 通过调用.next()方法,实现函数gen1的语句的分段执行
    
  • 使用for...of遍历函数执行后返回的迭代器对象,每一次遍历的item为yield后的表达式或者自变量的值

        function * gen1(){
            yield '耳朵' // 函数代码的分隔符
            yield '尾巴'
        }
    
        // 遍历,每一次遍历的item为yield后的表达式或者自变量的值
        for(let item of gen1()){
            console.log(item)
        }
        // 执行结果:
        // 耳朵
        // 尾巴
    
        // 注:next调用和for...of调用同时存在,只会支持最先的一个
    
  • 生成器函数的参数传递

        function * gen(args){
            console.log(args) // 'aaa'
            let one = yield 111
            console.log(one) // 'bbb'
    
            let two = yield 222
            console.log(two) // 'ccc'
            
            let three = yield 333
            console.log(three)
        }
    
        // 执行生成器函数获取迭代器对象
        let iterator = gen('aaa')
    
        console.log(iterator.next()) // {value: 111, done: false}
        // next方法可以传入实参,传入的实参会作为上一个yield后返回的结果
        console.log(iterator.next('bbb')) // {value: 222, done: false}
        console.log(iterator.next('ccc')) // {value: 333, done: false}
        console.log(iterator.next('ddd')) // {value: undefined, done: true}
    
  • 生成器函数实例1:
    1s后控制台输出111 --> 2s后控制台输出222 --> 3s后控制台输出333 ==> 总计耗时6s

       // 异步编程,如文件操作、网络请求、数据库操作
        // 1s后控制台输出111 --> 2s后控制台输出222 --> 3s后控制台输出333  ==> 总计耗时6s
    
        // 用生成器函数实现
        function one (){
            setTimeout(()=>{
                console.log(111)
                iterator.next()
            }, 1000)
        }
    
        function two (){
            setTimeout(()=>{
                console.log(222)
                iterator.next()
            }, 2000)
        }
    
        function three (){
            setTimeout(()=>{
                console.log(333)
            }, 3000)
        }
    
        function * gen(){
            yield one()
            yield two()
            yield three()
        }
    
        let iterator = gen()
        iterator.next()
        
    
        // 以下为回调地域做法
        // setTimeout(()=>{
        //     console.log(111)
        //     setTimeout(()=>{
        //         console.log(222)
        //         setTimeout(()=>{
        //             console.log(333)
        //         }, 3000)
        //     }, 2000)
        // }, 1000)
    
  • 生成器函数实例2:
    模拟获取 用户数据 --> 订单数据 --> 商品数据

        // 模拟获取 用户数据 --> 订单数据 --> 商品数据
        function getUsers(){
            setTimeout(()=>{
                let data = '用户数据'
                iterator.next(data) // 相当于把得到的数据,传回users
            }, 1000)
        }
    
        function getOrders(){
            setTimeout(()=>{
                let data = '订单数据'
                iterator.next(data)
            }, 2000)
        }
    
        function getGoods(){
            setTimeout(()=>{
                let data = '商品数据'
                iterator.next(data)
            },3000)
        }
    
        // 定义生成器函数
        function * gen (){
            let users = yield getUsers()
            console.log(users) // 用户数据
    
            let orders = yield getOrders()
            console.log(orders) // 订单数据
    
            let goods = yield getGoods()
            console.log(goods) // 商品数据
        }
    
        // 调用生成器函数,获取迭代器对象
        let iterator = gen()
        iterator.next()
    

12.Promise

Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

  1. Promise构造函数:Promise(excutor){}
  2. Promise.prototype.then方法
  3. Promise.prototype.catch方法

基本使用

        // 实例化Promise对象
        const p = new Promise(function(resolve, reject){
            setTimeout(()=>{
                let data = '数据库中的用户数据'
                // resolve(data)
                let err = '数据读取失败'
                reject(err)
            },1000)
        })

        p.then((value)=>{
            console.log('enter success')
            console.log(value)
        },err=>{
            console.log('enter failed')
            console.log(err)
        })

Promise封装读取文件

// 1.引入fs模块 fileSystem 文件系统
const fs = require('fs')

// 2.调用方法读取文件
// fs.readFile('./resource/file.md', (err, data)=>{ // data是一个buffer,用来存储2进制文件,用法跟数组类似
//     // 如果失败,抛出错误
//     if(err) throw err
//     // 如果成功,读取文件
//     console.log(data.toString())
// })

// 3.使用promise封装
const p = new Promise(function(resolve, reject){
    fs.readFile('./resource/file.md', (err,data)=>{
        if(err){
            reject(err)
        }else{
            resolve(data.toString())
        }
    })
})
p.then((value)=>{
    console.log(value)
},(reason)=>{
    console.error(reason)
})

Promise封装ajax

        // 接口地址:https://api.apiopen.top/getJoke
        // 原生ajax发送请求
        // // 1.创建对象
        // const xhr = new XMLHttpRequest()

        // // 2.初始化
        // xhr.open('GET', 'https://api.apiopen.top/getJoke')

        // // 3.发送
        // xhr.send()

        // // 4.绑定事件
        // xhr.onreadystatechange = function(){
        //     // 判断阶段
        //     if(xhr.readyState === 4 ){
        //         // 判断响应状态码
        //         if(xhr.status >= 200 && xhr.status < 300){
        //             // 如果状态码为成功,打印返回结果
        //             console.log(xhr.response)
        //         }else{
        //             // 如果失败
        //             console.error(xhr.status)
        //         }
        //     }
        // }


        // promise封装发送ajax请求
        const p = new Promise((resolve, reject)=>{
            const xhr = new XMLHttpRequest()
            xhr.open('GET', 'https://api.apiopen.top/getJoke')
            xhr.send()
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        resolve(xhr.response)
                    }else{
                        reject(xhr.status)
                    }
                }
            }
        })
        p.then((value)=>{
            console.log(value)
        },(reason)=>{
            console.log(reason)
        })

Promise.prototype.then方法

then方法的返回结果,依然是一个promise对象,其状态的成功或失败,由then里的回调函数的执行结果决定

  • 如果回调函数中返回的结果是非promise类型的属性,状态为成功,且return的结果就是该promise成功后resolve的值
    注: 如果没有return,则默认返回undefined,所以状态依然为成功

  • 如果返回的结果是promise对象,则该promise对象的状态就是then返回的promise对象的状态

  • 如果是抛出一个值(如一个错误),则状态为失败

        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('用户数据')
                // reject('出错啦')
            }, 1000)
        })
    
        const result = p.then((value)=>{ // p执行resolve后,状态为成功,执行第一个函数
            console.log(value )
            // 1.返回非promise对象的情况
            // return 233 // 233
            // 2.返回promise对象
            return new Promise((resolve, reject)=>{
                resolve('ok') // 状态为成功,值=ok
                // reject('error!!') // 状态为失败
    
            })
            // 3.抛出错误
            // throw new Error('error!!!')
        },(reason)=>{ // p执行reject后,状态为失败,执行第二个函数
            console.warn(reason)
        })
    
        // then方法的返回结果,依然是一个promise对象,其状态的成功或失败,由then里的回调函数的执行结果决定
        console.log(result)
    

then方法的这个特性,决定了then方法可以进行链式调用

        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('用户数据')
                // reject('出错啦')
            }, 1000)
        })

        // 链式调用
        p.then((value)={
            // ...
        }).then((value)=>{
            // ...
        })

通过链式调用实现按顺序读取文件

	// 1.引入fs模块 fileSystem 文件系统
	const fs = require('fs')
	
	// 使用传统方式实现 读取文件1 => 读取文件2 => 读取文件3
	// fs.readFile('./resource/file1.md', (err, data)=>{
	//     let data1 = data.toString()
	//     fs.readFile('./resource/file2.md', (err,data)=>{
	//         let data2 = data.toString()
	//         fs.readFile('./resource/file3.md', (err,data)=>{
	//             let data3 = data.toString()
	//             let data_all = {data1,data2,data3}
	//             console.log(data_all)
	//         })
	//     })
	// })
	
	// 使用promise方式实现 读取文件1 => 读取文件2 => 读取文件3
	const p = new Promise((resolve, reject)=>{
	    fs.readFile('./resource/file1.md', (err,data)=>{
	        resolve(data)
	    })
	})
	
	p.then((value) => {
	    return new Promise((resolve, reject)=>{
	        fs.readFile('./resource/file2.md',(err,data)=>{
	            let data_all =  {
	                data1: value.toString(),
	                data2: data.toString()
	            }
	            resolve(data_all)
	        })
	    })
	}).then((value)=>{
	    return new Promise((resolve,reject)=>{
	        fs.readFile('./resource/file3.md', (err,data)=>{
	            value.data3 = data.toString()
	            resolve(value)
	        })
	    })
	}).then(value=>{
	    console.log(value)
	    //  { data1: '# 这是文件1', data2: '# 这是文件2', data3: '# 这是文件3' }
	})

Promise对象catch方法

用于指定promise对象失败的回调

        const p = new Promise((resolve,reject)=>{
            setTimeout(()=>{
                // 设置p对象的状态为失败
                reject('opps error')
            },1000)
        })

        // p.then((value)=>{}, (reason)=>{
        //     console.error(reason)
        // })
        
        // 相当于then里面的第二个回调函数
        p.catch((reason)=>{
            console.warn(reason)
        })

13.set(集合)

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

  • size,返回集合的元素个数

  • add,增加一个新元素,返回当前集合

  • delete,删除元素,返回Boolean值

  • has,检测集合中是否包含某个元素,返回Boolean值

        let s = new Set(['风声','雨声','读书声','风声']) // 可以接受可迭代数据,一般传入数组
        // '风声','雨声','读书声'
    
        let size = s.size // 查看元素个数
        let has = s.has('读书声') // 检测是否含该元素 true
        s.add('水声') // 添加元素
        s.delete('读书声') // 删除元素
        let has2 = s.has('读书声') // 检测是否含该元素 false
        
        // 遍历集合
        for(let item of s){
            console.log(item)
        }
        s.clear() // 清空集合
    
        console.log(s, has,has2, typeof s)
    

set的应用

数组去重

        let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        // 数组去重
        let result = [...new Set(arr)]
        console.log(result) // [1, 2, 3, 4, 5]

求交集

        let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        let arr2 = [4, 5, 6, 5, 6]

        // 求交集
        let result = [...new Set(arr)].filter(item => { // 对arr去重并进行遍历
            let s2 = new Set(arr2) // 将arr2变为元素不重复的集合
            if(s2.has(item)){ // 如果元素存在s2中
                return true
            }else{
                return false
            }

        })
        console.log(result) // [4, 5]

        // 简化写法
        let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item))
        console.log(result2)

求并集

        let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        let arr2 = [4, 5, 6, 5, 6]

        // 求并集:连接两个数组 => 转为元素不重复的集合 => 转为数组
        let union = [...new Set([...arr, ...arr2])]
        console.log(union)
        // [1, 2, 3, 4, 5, 6]

求差集

        let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
        let arr2 = [4, 5, 6, 5, 6]

        // 求差集-arr对arr2求差集,即求arr里面有但是arr2里没有的元素,相当于求交集的逆运算
        let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
        console.log(diff) // [1, 2, 3]

14.Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用「扩展运算符」和for...of进行遍历
Map的属性和方法:

  • size,返回Map的元素个数

  • set,增加一个新元素,返回当前Map

  • get,返回键名对象的键值

  • has,检测Map中是否包含某个元素,返回Boolean值

  • clear,清空集合,返回undefined

        // 声明Map
        let m = new Map()
    
        // 添加元素
        m.set('name','LiMing') // 键名,键值
        m.set('tell',function(){
            console.log('I am LiMing ')
        })
        let friend = {
            school: '三中'
        }
        m.set(friend,['小吴','小王','小芳'])
    
        // 删除元素
        m.delete('tell')
    
        // 获取元素
        let friends = m.get(friend)
        console.log(friends)
    
        // 获取元素个数
        let size = m.size
        console.log(size)
    
        // 遍历Map
        for(let item of m){
            console.log('item---',item)
            // 每一个item都是一个数组,第一个元素为键,第二个元素为值
        }
        
        // 清空Map
        m.clear()
        console.log(m)
        console.log(typeof m)
    

class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值