ES6及以上语法(主代码)

1. 解构赋值

// 数组
let arr = ['apple', 'pear', 'bananar', 'sour'];
let [a, b, c, d] = arr;
console.log(a, b, c, d); // apple pear bananar sour
// 对象
let obj = {
    uname: 'Tom',
    age: 18,
    play: function() {
        console.log('like ping-pong');
    }
}
let {uname, age, play} = obj;
console.log(uname, age, play)
play(); // like ping-pong

2. 函数参数的默认值

// 默认放最后,否则可能导致出错
function fn(a, b, c=10) {
    return a + b + c;
}
let res = fn(1, 2);
console.log(res); // 13

3. rest参数

// 以前获取函数实参,伪数组
function fn1() {
    console.log(arguments); 
    // Arguments(3) ['Tom', 'Jerry', 'Lily', callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
fn1('Tom', 'Jerry', 'Lily');
​
// rest获取实参,真数组
function fn2(...args) {
    console.log(args); // ['cat', 'mouse', 'people']
}
fn2('cat', 'mouse', 'people');

4. 扩展用算符(…)

// 1、数组合并
let arr1 = [1, 2, 3, 4];
let arr2 = ['a', 'b'];
let newarr1 = arr1.concat(arr2);
let newarr2 = [...arr1, ...arr2];
console.log(newarr1, '-----', newarr2);
// 2、浅拷贝
let arr3 = ['sily', 3, 'haha'];
// let arr4 = arr3;不可取,当一个值发生改变,原数组和拷贝数组都发生改变
let newarr3 = [...arr3];
console.log(newarr3);
// 3、转为参数序列
function add(x, y) {
    return x + y;
}
let num = [10, 30];
let addRes = add(...num); // 40
// 4、与解构赋值结合,生成数组
let [num1, ...rest] = [1, 2, 3, 4, 5];
console.log(num1);// 1
console.log(rest);// [2, 3, 4, 5]
// 5、将字符串变为数组
let haha = [...'Hello']
console.log(haha); // ['H', 'e', 'l', 'l', 'o']
// 6、将伪数组转为真数组  
function fun() {
    const args = [...arguments];
    // const args = Array.prototype.slice.call(arguments); 也可以转化(ES5)
    console.log(args); // ['a', 'b', 'c']    
}
fun('a', 'b', 'c'); 
// 对象的扩展运算符
// 将对象中可枚举的属性进行浅拷贝
let oneobj = {
    sex: 'boy',
    age: 10,
    play() {
        console.log('happy');
    }
}
let shallow = {...oneobj}; // 等价与 Object.assign({}, oneobj)
shallow.play(); // happy
shallow.sex = 'girl';
console.log(shallow.sex, '===', oneobj.sex); // girl === boy

5. Symbol基本数据类型

// 创建一个独一无二的值,不能参与运算
let s1 = Symbol();
let s2 = Symbol('Tom');
let s3 = Symbol('Tom');
console.log(s2 == s3);// false
// Symbol.for  创建
let s4 = Symbol.for('Jerry');
let s5 = Symbol.for('Jerry');
console.log(s4 == s5);// true
// 创建对象属性
// 第一种
let origin = {
    name: 'haha',
    down: '下',
    up: '上',
}
let methods = {
    down: Symbol(),
    up: Symbol(),
}
origin[methods.down] = function() {
    console.log('this is down');
}
origin[methods.up] = function() {
    console.log('this is up');
}
​
// 第二种
let bar = {
    age: 19,
    [Symbol('play')]: function() {
        console.log('hahahah')
    }
}
console.log(bar)

6. iterator迭代器

  • 内置迭代器的有

    • Array

    • Arguments

    • Set

    • Map

    • String

    • TypedArray

    • NodeList

  • 工作原理

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

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

    • 不断调用next方法,指针一直向后移动知道最后一个成员

    • 每次调用next方法会返回一个包含value和done属性的对象,其中value为遍历对象的值,done为知否遍历完成;当遍历结束后{value:undefined,done:true}

    • ​需要自定义遍历数据时,可用迭代器
    // Symbol.iterator
    const arr = ['one', 'two', 'three'];
    let iterator = arr[Symbol.iterator]();
    console.log(iterator.next()); // {value: 'one', done: false}
  • 自定义遍历数据

    var xiyou = {
        author: '吴承恩',
        member: [
            '孙悟空',
            '唐僧',
            '猪八戒',
            '沙和尚'
        ],
        [Symbol.iterator]() {
            let i = 0;
            return {
                next: () => {
                    if (i < this.member.length) {
                        let res = {
                            value: this.member[i],
                            done: false
                        }
                        i++
                        return res;
                    } else {
                        return { value: undefined, done: true };
                    }
                }
            }
        }
    }
    for (let v of xiyou) {
        console.log(v); // 孙悟空 唐僧 猪八戒 沙和尚
    }

7. 生成器

function one() {
    setTimeout(() => {
        console.log('AAA');
        aterator.next()
    }, 1000);
}
function two() {
    setTimeout(() => {
        console.log('BBB');
        aterator.next()
    }, 2000);
}
function three() {
    setTimeout(() => {
        console.log('CCC');
        aterator.next()
    }, 3000);
}
​
function* gen() {
    yield one();
    yield two();
    yield three();
}
​
// 调用gen()
let aterator = gen();
aterator.next(); // 调用第一个函数 AAA
// aterator.next(); // 调用第二个函数 BBB
// aterator.next(); // 调用第三个函数 CCC
// 需求: 依次获取 用户数据 订单数据  产品数据
function userDate() {
    setTimeout(() => {
        let user = "用户数据";
        result.next(user)
    }, 1000);
}  
function orderDate() {
    setTimeout(() => {
        let order = "订单数据";
        result.next(order)
    }, 1000);
}
function goodsDate() {
    setTimeout(() => {
        let goods = "产品数据";
        result.next(goods)
    }, 1000);
}
​
function *totalRequire() {
    let getuser = yield userDate();
    console.log(getuser );// (隔一秒) 用户数据
    let getorder = yield orderDate();
    console.log(getorder);// (隔一秒) 订单数据
    let getgoods = yield goodsDate();
    console.log(getgoods);// (隔一秒) 产品数据
}
​
let result = totalRequire();
result.next();

8. Promise

  • Promise的状态:(实例对象中的一个属性【PromiseState】)

    • pending:未决定的(初始默认)

    • resolved / fullfilled:成功

    • rejected:失败

  • Promise状态改变:

    • pending变为resolved

    • pending变为rejected

    • 一个promise对象只能改变一次,无论成功失败都有一个结果数据

  • Promise对象的值:(实例对象中的一个属性【PromiseResult】,异步保存对象【成功/失败】的结果)

    • resolve

    • reject

(1)利用Promise读取多个文件, 解决回调地狱

const fs = require('fs');
​
let p = new Promise((resolve, reject) => {
    fs.readFile('./files/cat.txt', (err, data) => {
        if (err) reject(err);
        resolve(data)
    })
})
p.then((value) => {
    // console.log(value.toString());
    return new Promise((resolve, reject) => {
        fs.readFile('./files/dog.txt', (err, data) => {
            if (err) reject(err);
            resolve([value, data]);
        })
    })
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile('./files/people.txt', (err, data) => {
            if (err) throw err
            value.push(data)
            resolve(value)
        })
    })
}).then(value => {
    console.log(value.join('\n\r'));
})

(2)Promise封装ajax操作

<body>
    <div>
        <h1>封装ajax操作</h1>
        <button class="btn">获取</button>
    </div>
    <script>
        const btn = document.querySelector('.btn');
        btn.onclick = function() {
            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((val) => {
                console.log(val);
            }, (err) => {
                console.warn(err);
            })
        }
    </script>
</body>
function sendAJAX(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.responseType = 'json';// 返回响应体的格式
        xhr.open('GET', url);
        xhr.send();
        xhr.onreadystatechange = function() {
            if(xhr.readyState = 4) {
                if(xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response);
                }else {
                    reject(xhr.status);
                }
            }
        }
    })
}
// 使用
sendAJAX('https://api.apiopen.top/getJoke').then(val => {
    console.log(val)
}).catch(err => {
    console.log(err)
})

(3)Promise封装fs读取文件

const fs = require('fs');
// 封装函数
function toReadFiles(path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, (err, data) => {
            if (err) reject(err)
            resolve(data)
        })
    })
}
// 执行
toReadFiles('./files/cat.txt').then(val => {
    console.log(val.toString());
}, err => {
    console.log(err);
})

(4)fs读取文件借助内置方法util

// 借助内置方法util.promisify()
const util = require('util');
const fs = require('fs');
let myReadFile = util.promisify(fs.readFile);
myReadFile('./files/dog.txt').then(val => {
    console.log(val.toString());
}).catch(err => {
    console.log(err);
})

(5)Promise的API

  • Promise.resolve(参数)

    • 参数为非Promise类型的对象,返回的结果为成功的promise对象

    • 参数为Promise对象,则参数的结果决定了resolve的结果

    let p1 = Promise.resolve(520)
    console.log(p1);
    ​
    let p2 = Promise.resolve(new Promise((resolve, reject) => {
        // resolve('ok')
        reject('err')
    }))
    // console.log(p2);
    p2.catch(err => {
        console.log(err);
    })
  • Promise.reject(参数):无论传入什么参数,状态是失败的状态,结果是传入的值

  • Promise.all (由promise组成的数组):所有的promise对象全部成功,才返回成功,且值为所有promise结果组成的数据;如果有失败,值为失败的那个值

    let p1 = new Promise((resolve, reject) => {
        resolve('ok');
    })
    let p2 = Promise.resolve('成功');
    let p3 = Promise.resolve('hahahah');
    ​
    let resultFinal = Promise.all([p1, p2, p3])
    console.log(resultFinal);

    let p1 = new Promise((resolve, reject) => {
        resolve('ok');
    })
    let p2 = Promise.reject('Error');
    let p3 = Promise.resolve('hahahah');
    ​
    let resultFinal = Promise.all([p1, p2, p3])
    console.log(resultFinal);

  • Promise.race(由promise组成的数组):哪个先执行,哪个为最终结果

(6)关键问题

  • ① Promise对象状态改变的方式

    let p = new Promise((resolve, reject) => {
        // 1. 
        //resolve('oj');
        // 2.
        //reject('err');
        // 3. 抛出错误
        //throw "error"
    })
  • ② Promise对象指定多个成功或失败的回调(then/catch),当promise改变状态时,都会调用

  • ③ 改变promise状态和指定回调函数谁先谁后?

    • 都有可能,当new Promise(function)里封装的是同步任务,先改状态再回调;当是异步任务,先回调再改状态

    • 得到数据:①先指定回调,当状态发生改变,回调函数就会调用,得到数据;②先改变状态,当指定回调时,回调函数调用得到数据。

  • ④ promise.then() 返回新的promise结果状态由then() 指定的回调函数执行结果决定

    • 如果抛出异常(throw error),新promise变为rejected

    • 如果返回非promise的任意值,新promise为resolved

    • 如果返回promise,它的结果为新promise的结果

  • ⑤ promise如果串联多个操作任务?

    • 通过then的链式调用

  • ⑥ promise异常传透?

    • 通过then链式调用时,可以在最后指定失败的回调(catch)

    • 前面任何操作出异常,都会传到最后失败的回调中处理

  • ⑦ 中断promise链?

    • 回调函数中返回一个pendding状态的promise对象

    let  p = new Promise((resolve, reject) => {
        resolve('ok');
    })
    p.then(val => {
        console.log('111')
        return new Promise(() => {})
    }).then(val => {
        console.log('222')
    })

9. async函数

  • async函数的返回值是promise对象

  • promise对象的结果由async函数执行的返回值决定(同then的)

  • await表达式

    • await右侧的表达式一般为promise对象,也可以是其他值

    • 表达式如果是promise对象,await返回的是promise成功的值

    • 表达式时其他值,直接将此值作为await的返回值

// 获取多个文件的数据
const fs = require('fs');
const util = require('util');
const myReadFile = util.promisify(fs.readFile);
​
async function getFilesData() {
    try {
        const file1 = await myReadFile('./files/cat.txt');
        const file2 = await myReadFile('./files/dog.txt');
        const file3 = await myReadFile('./files/people.txt');
        console.log(file1 + file2 + file3);
    } catch (error) {
        console.log(error);
    }
}
getFilesData()

10. Set

// 声明一个set
let s = new Set();
let s2 = new Set(['good', 'nice', 'prefect', 'great']);
​
console.log(s2.size);// 4
// 添加
s2.add('wonderfull');
console.log(s2);
// 删除
s2.delete('nice')
// 是否存在
console.log(s2.has('nice'));// false
// 清空
// s2.clear()
console.log(s2);
​
for(const v of s2) {
    console.log(v);
}
  • ① 数组去重

    let arr1 = [1, 2, 3, 4, 5, 5, 5, 4, 3, 2];
    ​
    console.log(new Set(arr1)); // Set(5) { 1, 2, 3, 4, 5 }
    let res1 = [...new Set(arr1)];
    console.log(res1);// [ 1, 2, 3, 4, 5 ]
  • ② 交集

    let arr1 = [1, 2, 3, 4, 5, 5, 5, 4, 3, 2];
    let arr2 = [3, 3, 4, 4, 6];
    ​
    let res2 = [...new Set(arr1)].filter(item => new Set(arr2).has(item));
    console.log(res2);// [ 3, 4 ]
  • ③ 并集

    let arr1 = [1, 2, 3, 4, 5, 5, 5, 4, 3, 2];
    let arr2 = [3, 3, 4, 4, 6];
    ​
    let res3 = [...new Set([...arr1, ...arr2])]
    console.log(res3); // [ 1, 2, 3, 4, 5, 6 ]
  • ④ 差集

    let arr1 = [1, 2, 3, 4, 5, 5, 5, 4, 3, 2];
    let arr2 = [3, 3, 4, 4, 6];
    ​
    let res4 = [...new Set(arr1)].filter(item => !(new Set(arr2).has(item)));
    console.log(res4); // [ 1, 2, 5 ]

11. Map

let map = new Map();
​
// 1. 设置, key和value, 类型为任意
map.set('name', 'Tom');
map.set(2, function(){
    console.log('haha');
})
map.set({xixi: '嘻嘻'}, true);
// 2. 个数
console.log(map.size); // 3
// 3. 查找
console.log(map.get(2));
// 4. 删除
map.delete('name');
// 5. 是否存在
console.log(map.has('name'));// false
console.log(map);
// 6. 清空
map.clear();

12. Class

  • class关键字

class Cat {
    // 构造函数
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
​
    sayHi() {
        console.log('miao~');
    }
}
const cat = new Cat('Tom', 2);
console.log(cat.name, cat.age); //Tom 2
cat.sayHi(); //miao~
  • static静态属性,实例无法使用

function Phone() {
​
}
​
Phone.name = 'Huawei';
Phone.price = 4999;
Phone.prototype.call = function() {
    console.log('can all somebody');
}
​
const huawei = new Phone();
console.log(huawei.name, huawei.price); // undefined undefined
huawei.call();// can all somebody
​
class Phone2 {
    name = "Xiaomi";
    price = 2999;
    // static 静态属性
    static color = "black";
}
​
const xiaomi = new Phone2()
console.log(xiaomi.name, xiaomi.price); // Xiaomi 2999
console.log(xiaomi.color); // undefined
  • 继承

// ES5原型继承
function Phone3(brand, price) {
    this.brand = brand;
    this.price = price;
​
    this.call = function() {
        console.log('打电话');
    }
}
​
function SmartPhone(brand, price, color, size) {
    Phone3.call(this, brand, price);
    this.color = color;
    this.size = size;
}
​
SmartPhone.prototype = new Phone3;
SmartPhone.prototype.constructor = SmartPhone;
​
SmartPhone.prototype.chat = function() {
    console.log('聊微信');
}
SmartPhone.prototype.movie = function() {
    console.log('看电影');
}
​
const smartphone = new SmartPhone('iPhone', 5999, 'white', '5.5inch');
console.log(smartphone.brand, smartphone.price, smartphone.color, smartphone.size); // iPhone 5999 white 5.5inch
smartphone.call(); // 打电话
smartphone.chat(); // 聊微信
smartphone.movie(); // 看电影
​
// class类继承
class Father {
    constructor(house, money) {
        this.house = house;
        this.money = money;
    }
​
    play() {
        console.log('打牌');
    }
}
​
class Son extends Father{
    constructor(house, money, cat , car) {
        super(house, money);
        this.cat = cat;
        this.car = car;
    }
    learn() {
        console.log('study hard');
    }
    play() {
        console.log('打球');
    }
}
const son = new Son(1, '100RMB', 'Tom', 'BMW');
console.log(son); // Son { house: 1, money: '100RMB', cat: 'Tom', car: 'BMW' }
son.play(); // 打牌 重新改写后为 打球
son.learn(); // study hard
  • get和set

class Dog {
    constructor(name) {
        this._name = name;
    }
  
    // 获取属性
    get name() {
        console.log('拿到了属性值');
        return this._name;
    }
    // 设置属性
    set name(newVal) {
        console.log('设置了属性值');
        this._name = newVal;
    }
}
const dog = new Dog('Dark');
console.log(dog.name); // Dark
dog.name = 'heihei'
console.log(dog.name); // heihei

13. 模块化

  • 好处:

    • 防止命名冲突

    • 代码复用

    • 高维护性

  • ES6之前的模块化规范:

    • CommonJS => NodeJS、Browserify

    • AMD => requireJS

    • CMD => seaJS

  • ES6模块化语法

    • export

    • import

    // 暴露方式: (文件m1.js)
    // 1、分别暴露
    export let school = "Ming";
    export function goto() {
        console.log('go to Ming School');
    }
    ​
    // export {school, goto} 2、统一暴露
    ​
    // 3、默认暴露
    /* export default {
        xxx
    }*/
    ​
    // 引入方式:(文件m1.js暴露的东西)
    // 1、通用的导入放肆
    import * as m1 from './m1.js'
    // 2、解构赋值的方式
    import {school, goto} from './m1.js'
    // 3、简便形式  只针对默认暴露
    import m1 from './m1.js'

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值