JavaScript-ES6-基础语法二

1. Symbol

1.1. Symbol介绍

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

Symbol特点:

  • Symbol 的值是唯一的,用来解决命名冲突的问题
  • Symbol值不能与其他数据进行运算
  • Symbol定义的对象属性不能使用for…in 循环遍历, 但是可以使用Reflect.ownKeys来获取对象的所有键名
// create symbol
let s = Symbol()
console.log('s: ', s)   // Symbol()
console.log('type of s: ', typeof s)  // symbol

// create symbol with value
let s2 = Symbol('michael')
let s3 = Symbol('michael')
console.log('s2: ', s2)   // Symbol(michael)
console.log('s3: ', s3)   // Symbol(michael)
console.log(s2 === s3)    // false

// create symbol with Symbol.for
let s4 = Symbol.for('michael')
let s5 = Symbol.for('michael')
console.log('s4: ', s5)   // Symbol(michael)
console.log('s5: ', s5)   // Symbol(michael)
console.log(s4 === s5)    // true

// can not be calculated with other data
//    let result = s + 100;
//    let result = s > 100;
   let result = s + s;   // TypeError: Cannot convert a Symbol value to a number

// data type in js
// USONB  you  are so niubility

// u undefined
// s string symbol
// o object
// n null number
// b boolean

1.2. Symbol内置值

  • Symbol.hasInstance:当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
  • Symbol.isConcatSpreadable:对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。
  • Symbol.species:创建衍生对象时,会使用该属性Symbol.match当执行str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。
  • Symbol.replace:当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。
  • Symbol.search:当该对象被str. search (myObject)方法调用时,会返回该方法的返回值。
  • Symbol.split:当该对象被str. split (myObject)方法调用时,会返回该方法的返回值。
  • Symbol.iterator:对象进行for…of循环时,会调用 Symbol.iterator方法,返回该对象的默认遍历器
  • Symbol.toPrimitive:该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
  • Symbol. toStringTag:在该对象上面调用toString方法时 ,返回该方法的返回值
  • Symbol. unscopables:该对象指定了使用with关键字时,哪些属性会被 with环境排除。

// Symbol.hasInstance
class Michael{
    static [Symbol.hasInstance](param){
        console.log(param)
        console.log('here is the stataic method from Michael class')
        return true
    
    }

    o = {}

}
let o1 = {}

console.log(o1 instanceof Michael)   // true

// Symbol.isConcatSpreadable

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

console.log(arr.concat(arr2))  // [ 1, 2, 3, 4, 5, 6 ]

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

2. 迭代器

2.1. 迭代介绍

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

  • ES6新提供了一种遍历命令for…of循环,Iterator接口主要供for…of消费
  • 原生具备iterator接口的数据(可用for…of遍历)
    Array
    Arguments
    Set
    Map
    String
    TypedArray
    NodeList
  • 工作原理
    创建一个指针对象,指向当前数据结构的起始位置
    第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    接下来不断调用next方法,指针一直往后移动,知道指向最后一个成员
    每次调用next方法返回一个包含value和done属性的对象

Tip: 需要自定义遍历数据的时候,一般使用迭代器

// state an array
const blackpink = ['lisa', 'rose', 'jisoo', 'jenny']

// for...of 
for(let item of blackpink){
    console.log('girl group member: ', item)
}

let iterator = blackpink[Symbol.iterator]()

// call the next method of object
console.log(typeof iterator)

console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())

2.2. 自定义迭代器实现

const michael = {
    name: 'michael',
    members: [
        'lisa',
        'rose',
        'jisoo',
        'jenny'
    ],
    // [Symbol.iterator](){
    //     // index variable
    //     let index = 0
    //     let _this = this
    //     return {
    //         next:function(){
    //             if (index < _this.members.length) {
    //                 const result = { value: _this.members[index], done: false}
    //                 index++
    //                 return result
    //             }else{
    //                 return {value:undefined, done: true}
    //             }
    //         }
    //     }
    // }
    // arrow function implement
    [Symbol.iterator](){
        // index variable
        let index = 0
        return {
            next: () => {
                if (index < this.members.length){
                    const result = {value: this.members[index], done: false}
                    index++
                    return result
                }else{
                    return {value:undefined, done: true}
                }
            }
        }
    }

}

// iterate over the object
for (item of michael) {
    console.log('member from michael: ', item)
}

3. 生成器

3.1. 生成器介绍

// generator is actually a special function
// asynchronous program , callback function
function * gen(){
    console.log('first step')
    yield 'return after first step'

    console.log('second step')
    yield 'return after second step'

    console.log('third step')
    yield 'return after third step'

    console.log('last step')
}

let iterator = gen()
console.log('type of generator function: ', typeof iterator)
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())

for (item of iterator) {
    console.log(item)
}

3.2. 带参数生成器使用

// state generator function
function * generator(arg){
    console.log(arg)
    let one = yield 'first step'

    console.log(one)
    let two = yield 'second step'

    console.log(two)
    let three = yield 'third step'

    console.log(three)
}

// get the iterated object
let iterator = generator('aaa')

console.log(iterator.next())

// assgin the value
console.log(iterator.next('bbb'))
console.log(iterator.next('ccc'))
console.log(iterator.next('ddd'))

3.3. 生成器解决回调地狱问题

// requirement: output 111 after 1 second, output 222 after 2 second, output 333 after 3 second
// call back hell
// output 111 after 1 second
// setTimeout(()=>{
//     console.log(111)
//     // output 222 after 2 second
//     setTimeout(()=>{
//         console.log(222)
//         // output 333 after 3 second
//         setTimeout(()=>{
//             console.log(333)
//         }, 3000)
//     }, 2000)
// }, 1000)


// generator function
function one(){
    setTimeout(()=>{
        console.log(111)
        iterator.next()
    }, 1000)
}
function two(){
    setTimeout(()=>{
        console.log(222)
        iterator.next()
    }, 2000)
}
function three(){
    setTimeout(()=>{
        console.log(333)
        iterator.next()
    }, 3000)
}

function * gen(){
    yield one()
    yield two()
    yield three()
}

let iterator = gen()

iterator.next()

3.4. 生成器异步回调demo

// imitate get user data, order data, goods data
function getUsers(){
    setTimeout(()=>{
        let data = 'user data'
        // call next method, and pass the user data
        iterator.next(data)
    }, 1000)
}

function getOrders(){
    setTimeout(()=>{
        let data = 'order data'
        iterator.next(data)
    }, 1000)
}

function getGoods(){
    setTimeout(()=>{
        let data = 'goods data'
        iterator.next(data)
    }, 1000)
}

// generator function
function * generator(){
    let users = yield getOrders()
    console.log('users: ', users)

    let orders = yield getOrders()
    console.log('orders: ', orders)

    let goods = yield getGoods()
    console.log('goods: ', goods)
}

// call the generator function
let iterator = generator()
iterator.next()

4. Promise

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

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

4.1 Promise基本使用

// new promise object
const p = new Promise(function(resolve, reject){
    setTimeout(function(){
        // let data = 'user data from DB'
        // resolve(data)

        // imitate error
        let error = 'get data from DB error'
        reject(error)
    }, 1000)
})

// call the then mothod of promise object
p.then(function(value){
    console.log('value: ', value)
}, function(reason){
    console.log('reason: ', reason)
})

4.2. Promis封装读取文件

// import fs module
const fs = require('fs')

// 1. common method to read file
// fs.readFile('./data/learn.md', (err, data)=>{
//     // throw it if there is an error
//     if (err) throw err
//     // print the content if read successfully
//     console.log('content from learn.md: ', data.toString())
// })

// 2. use Promise object to read file
const p = new Promise(function(resolve, reject){
    fs.readFile('./data/learn.md', (err, data)=>{
        // call reject method if there is an error
        if(err) reject(err)

        // call resolve if read successfully
        resolve(data)
    })
})

p.then(function(value){
    console.log('content from learn.md: ', value.toString())
}, function(reason){
    console.log('read file error: ', reason)
})

在这里插入图片描述

4.3. Promis封装Ajax

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>send AJAX request</title>
</head>

<body>
    <script>
    // send ajax request
    const p = new Promise((resolve, reject)=>{
        // 1. creat ajax object
        const xhr = new XMLHttpRequest()

        // 2. initialization
        xhr.open('GET', 'https://0io8iqa8tj.execute-api.ap-southeast-1.amazonaws.com/prod/applicant/company')

        // 3. send request
        xhr.send()

        // 4. bind event, dealwith response
        xhr.onreadystatechange = function(){
            // state judgement
            if (xhr.readyState === 4) {
                // status judgement
                if (xhr.status >= 200 && xhr.status < 300){
                    resolve(xhr.response)
                } else {
                    reject(xhr.status)
                }
            }
        }

    })

    // define callback method
    p.then(function(value){
        console.log('response: ', value)
    }, function(reason){
        console.log('request error: ', reason)
    })
    </script>
</body>
</html>

4.4. Promise then方法

const p = new Promise((resolve, reject)=>{
    setTimeout(()=>{
        let data = 'get data from server end'
        resolve(data)
    }, 1000)
})


// call then method return Promise object, the status of Promise object is determined by the execution result of callback method
// 1. if the result of callback method is non-Promise field and status is successful,
//     the return value is the sucess valuf of Promise object
const result = p.then(value =>{
    console.log(value)
    return 'there is the love'
}, reason => {
    console.warn(reason)
})

console.log(result)  // Promise with resolve

// const result2 = p.then(value =>{
//     console.log(value)
//     // throw error
//     throw new Error('something wrong')
// }, reason => {
//     console.warn(reason)
// })

// console.log(result2)  // throw new Error('something wrong')

// 2. if the result of callback method is a Promise object ,then keep the same result
const result3 = p.then(value =>{
    console.log(value)
    // return Promise object
    return new Promise((resolve, reject)=>{
        resolve('okay')
        // reject('error')
    })
}, reason => {
    console.warn(reason)
})

console.log(result3)  // return promise with resolve

4.5. Promise catch 方法

// define a Promise object
const p = new Promise((resolve, reject) => {
    setTimeout(()=>{
        // set the status of p object is failed, and set the failed value
        reject('something wrong!!!')
    }, 1000)
})

// p.then((value)=>{}, (reason)=>{
//     console.error(reason)
// })

p.catch((reason) => {
    console.warn(reason)
})

4.6. Promis读取多个文件实战

// import fs
const fs = require('fs')

// common method to read multiple files at the same time
// fs.readFile('./data/learn.md', (err, data)=>{
//     fs.readFile('./data/poem.md', (err, data1) => {
//         fs.readFile('./data/readingFeeling.md', (err, data2) => {
//             let result = data + data1 + data2
//             console.log(result)
//         })
//     })
// })

// Promise
const p = new Promise((resolve, reject) => {
    // read the first file
    fs.readFile('./data/learn.md', (err, data) => {
        if (err) reject(err)
        resolve(data)
    })
})

// read the second file
p.then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile('./data/poem.md', (err, data) => {
            if (err) reject(err)
            resolve([value, data])
        })
    })
}, reason => {
    console.error(reason)
    // read the third file
}).then((value) => {
    return new Promise((resolve, reject) => {
        fs.readFile('./data/readingFeeling.md', (err, data) => {
            if(err) reject(err)

            value.push(data)
            resolve(value)
        })
    })
}, (reason) => {
    console.error(reason)
}).then(value => {
    console.log(value.join('/r/n'))
}, reason => {
    console.error(reason)
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值