ECMAScript知识点整理 - ES6(二)

本文详细讲解了Promise的基本使用、封装文件读取与AJAX请求,以及Set、Map的数据操作。同时涵盖ES6类的定义、继承和方法,还有ES6的数值扩展和对象方法。理解这些内容,提升异步编程和数据结构应用能力。
摘要由CSDN通过智能技术生成

目录

一、Promise(重要)

1.1 Promise介绍和基本使用

1.2 Promise封装读取文件

1.3 Promise封装AJAX请求

1.4 Promise-then方法

1.4.1 返回的结果是 非promise 类型

1.4.2 返回的结果是 Promise 对象

1.4.3 返回结果为抛出错误

1.4.4 then方法的链式调用

1.4.5 Promise 案例练习 - 多个文件内容读取

1.5 Promise对象catch方法

二、Set(集合)

2.1 集合属性和方法

2.2 集合案例练习

2.2.1 数组去重

2.2.2 交集

2.2.3 并集

2.2.4 差集

三、Map

2.1 Map的属性和方法

四、Class类

4.1 Class介绍

4.2 constructor 定义构造函数初始化

4.2.1 ES5 语法

4.2.2 ES6 class语法

4.3 static 定义静态方法和属性

4.4 extends 继承父类

4.4.1 ES5 构造函数继承

4.4.2 class的类继承

4.5 子类对父类方法的重写

4.6 class中的getter和setter设置

五、ES6的数值扩展

5.1 Number.EPSILON

5.2 二进制和八进制

5.3 Number.isFinite() 与 Number.isNaN()

5.4 Number.parseInt() 与 Number.parseFloat()

5.5 Number.isInteger()

5.6 Math.trunc()

5.7 Math.sign()

六、ES6的对象方法扩展

6.1 Object.is()

6.2 Object.assign()

6.3  setPrototypeOf()、setPrototypeOf() 

七、模块化

7.1 模块化介绍

7.1.1 模块化的好处

7.1.2 模块化规范产品

7.2 ES6模块化语法

7.3 ES6暴露(导出)数据语法汇总

7.3.1 逐个导出模块

7.3.2 统一导出模块

7.3.3 默认导出模块

7.4 ES6引入数据语法汇总

7.4.1 通用的导入方式

7.4.2 解构赋值形式

7.4.3 简便形式(针对默认导出语法)

7.5 浏览器使用ES6模块化方式二

7.6 babel对ES6模块化代码转化

7.6.1 步骤

八、ES6模块化引入NPM包

8.1 安装

8.2 导入


一、Promise(重要)

1.1 Promise介绍和基本使用

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

  1. Promise 构造函数:Promise(excutor){}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法
        // 实例化 Promise 对象
        const p = new Promise(function(resolove, reject){
            setTimeout(function(){
                // let data = '数据库中的用户数据';
                // resolove(data);
                let err = '数据读取失败';
                reject(err);
            });
        }, 1000);

        // 调用 promise 对象的 then方法
        p.then(function(value){
            console.log(value);
        },function(reason){
            console.log(reson);
        })

1.2 Promise封装读取文件

// 1. 引入fs 模块
const fs = require('fs');

// 2. 一般写法 调用方法读取文件
// fs.readFile('./测试.md', (err, data) => {
//     // 如果失败,则抛出错误
//     if(err) throw err;
//     // 如果未出错,则输出内容
//     console.log(data.toString());
// });

// 3. 使用 Promse 封装
const p = new Promise(function(resolve, reject){
    fs.readFile('./测试.md', (err, data)=>{
        if(err) reject(err);
        resolve(data);
    });
});

p.then(function(value){
    console.log(value.toString());
},function(reason){
    console.log('读取失败');
});

1.3 Promise封装AJAX请求

可以自己创建一个服务器尝试

server.js

const express = require('express');

// 2. 创建应用对象
const app = express();

// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');

    // 设置响应体
    response.send('HELLO AJAX-2');
    
});

app.post('/server', (request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');

    // 设置响应体
    response.send('HELLO AJAX POST');
    
});

 promise封装AJAX请求.html

    <script>
        const p = new Promise((resolve, reject)=>{
            // 1. 创建对象
            const xhr = new XMLHttpRequest();
            // 2. 初始话
            xhr.open('GET','http://127.0.0.1:8000/server');
            // 3. 发送
            xhr.send();
            // 4. 绑定事件,处理响应结果
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        resolve(xhr.response);
                    } else {
                        reject(xhr.status);
                    }
                }
            }
        });

        p.then(function(value){
            console.log(value);
        },function(reason){
            console.error(reason);
        });
    </script>

1.4 Promise-then方法

then方法返回结果是 Promise 对象, 对象状态由调用函数的执行结果决定

首先创建Promise对象

        // 创建 Promise对象
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                resolve('用户数据')
            },1000);
        });

1.4.1 返回的结果是 非promise 类型

调用then方法

如果调用函数中返回的结果是 非promise 类型的属性,状态为成功,返回值为对象的成功的值,且then方法返回 Promise 对象状态为成功

注意:默认值undefined 同样为非promise类型

        // 调用then方法
        // 如果调用函数中返回的结果是 非promise 类型的属性,状态为成功,返回值为对象的成功的值
        const result = p.then(value=>{
            console.log(value);
            // 1. 非prominse 类型的属性,注意 默认值undefined 同样为非promise类型
            return 123;
        }, reason=>{
            console.warn(reason);
        });

        console.log(result);

1.4.2 返回的结果是 Promise 对象

当返回的结果是 Promise 对象该 Promise 对象 状态为成功,then方法返回结果的Promise 对象 返回值为 该Promise 对象的返回值,反之亦然

        const result = p.then(value=>{
            console.log(value);
            // 2. 是promise 对象
            return new Promise((resolve, reject)=>{
                resolve('ok')
            });
        }, reason=>{
            console.warn(reason);
        });

        console.log(result);

该Promised对象,状态为失败时,then方法返回结果的Promise 对象 与之相对应

            // 2. 是promise 对象
            return new Promise((resolve, reject)=>{
                reject('error')
            });

then方法返回的结果也为失败

1.4.3 返回结果为抛出错误

抛出错误时,then方法返回结果的Promise 对象状态也为失败

        const result = p.then(value=>{
            console.log(value);
            // 3. 抛出错误
            // throw new Error('出错啦');
            throw '出错啦';
        }, reason=>{
            console.warn(reason);
        });

        console.log(result);

1.4.4 then方法的链式调用

通过链式调用改变回调地狱现象

p.then(value=>{},reason=>{}).then(value=>{},reason=>{});

1.4.5 Promise 案例练习 - 多个文件内容读取

依据 then方法的链式调用 解决回调地狱现象

 传统方式

const fs = require('fs');

fs.readFile('./测试.md', (err,data1)=>{
    fs.readFile('./测试2.md', (err,data2)=>{
        fs.readFile('./测试3.md', (err,data3)=>{
            let result = data1 + '\r\n' + data2 + '\r\n' + data3;
            console.log(result);
        });
    });
});

使用 promise 实现

// 使用 promise 实现
const p = new Promise((resolve,reject)=>{
    fs.readFile('./测试.md', (err,data)=>{
        resolve(data);
    });
});
p.then(value=>{
    return new Promise((resolve,reject)=>{
        fs.readFile('./测试2.md', (err,data)=>{
            resolve([value,data]);
        });
    });
}).then(value=>{
    return new Promise((resolve,reject)=>{
        fs.readFile('./测试3.md', (err,data)=>{
            value.push(data);
            resolve(value);
        });
    });
}).then(value=>{
    console.log(value.join('\r\n'));
});

1.5 Promise对象catch方法

catch方法是.then(null, reject)的别名,用于指定发生错误时的回调函数

    <script>
        const p = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                reject('出错!');
            }, 1000);
        });

        p.catch(function(reason){
            console.warn(reason);
        });
    </script>

二、Set(集合)

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator接口,所以可以使用 扩展运算符( ... ) 和 for…of… 进行遍历

2.1 集合属性和方法

size返回集合的元素个数
add增加一个新元素,返回当前集合
delete删除元素,返回 boolean 值
has鉴差集合中是否包含某个元素,返回boolean值
        let s = new Set();
        let s2 = new Set(['电脑','手机','座机','电视','手机']);

        // 元素个数
        // console.log(s2.size);
        // 添加新元素
        // s2.add('游戏机');
        // 删除元素
        // s2.delete('电脑');
        // 检测
        // console.log(s2.has('游戏机'));
        // console.log(s2);

        for(let v of s2){
            console.log(v);
        }

2.2 集合案例练习

        let arr = [1,2,3,4,5,4,3,2,1];

2.2.1 数组去重

        // 数组去重
        let result = [...new Set(arr)];
        console.log(result);

2.2.2 交集

        let arr2 = [4,5,6,8,4,5];
        let result = [...new Set(arr)].filter(item=>{
            let s2 = new Set(arr2);
            if(s2.has(item)){
                return true;
            } else {
                return false;
            }
        });
        console.log(result);

简化写法

        let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item));
        console.log(result2);

2.2.3 并集

        let arr2 = [4,5,6,8,4,5];
        let union = [...new Set([...arr, ...arr2])];
        console.log(union);

2.2.4 差集

        let arr2 = [4,5,6,8,4,5];
        let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
        console.log(diff);

三、Map

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

2.1 Map的属性和方法

size返回Map的元素个数
set增加一个新元素,返回当前Map
get返回键名对象的键值
has检测Map中是否包含某个元素,返回boolean值
clear清空集合,返回undefined
        // 声明 Map
        let m = new Map();

        // 添加元素
        m.set('name','承太郎');
        m.set('boxing',function(){
            console.log('会拳击');
        });
        let key = {
            artName : 'JOJO'
        };
        m.set(key,['白金之星','欧拉','世界'])

        // size
        // console.log(m.size);

        // 删除


        // 获取
        // console.log(m.get('boxing'));
        // console.log(m.get(key));

        // 清空
        // m.clear();

        // 遍历
        for(let v of m){
            console.log(v);
        }
        console.log(m);

四、Class类

4.1 Class介绍

ES6 提供了更接近传统语言的写法,引入Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6的 class 类可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更清晰、更面向对象编程的语法而已

知识点:

  1. class声明类
  2. constructor 定义构造函数初始化
  3. extends 继承父类
  4. super 调用父级构造方法
  5. static 定义静态方法和属性
  6. 父类方法可以重写

4.2 constructor 定义构造函数初始化

4.2.1 ES5 语法

        // ES5 语法
        function Phone(brand, price){
            this.brand = brand;
            this.price = price;
        }

        // 添加方法
        Phone.prototype.call = function(){
            console.log('通话功能');
        }

        // 实例化对象
        let Huawei = new Phone('华为', 5999);
        Huawei.call();
        console.log(Huawei);

4.2.2 ES6 class语法

        // class 语法
        class Phone2{
            // 构造方法 名字不能修改
            constructor(brand,price){
                this.brand = brand;
                this.price = price;
            }
            // 方法必须使用该语法,不能使用 ES5 的对象完整形式
            call(){
                console.log('通话功能');
            }
        }
        let xiaomi = new Phone2('xiaomi', 1999);
        console.log(xiaomi);

4.3 static 定义静态方法和属性

被static 标注的属性和方法属于类,而不属于实例化对象

        class Phone{
            static name = '手机';
            static call(){
                console.log('通话功能');
            }
        }
        let xiaomi = new Phone();
        console.log(xiaomi.name);
        console.log(Phone.name);

4.4 extends 继承父类

4.4.1 ES5 构造函数继承

        // 父类
        function Phone(brand,price){
            this.brnad = brand;
            this.price = price;
        }
        Phone.prototype.callme = function(){
            console.log('通话功能');
        }
        
        // 子类
        function smartPhone(brand, price, color, size){
            Phone.call(this, brand, price);
            this.color = color;
            this.size = size;
        }

        // 设置子级构造函数的原型
        smartPhone.prototype = new Phone;
        smartPhone.prototype.constructor = smartPhone;

        // 声明子类的方法
        smartPhone.prototype.photo = function(){
            console.log('拍照功能');
        }
        smartPhone.prototype.game = function(){
            console.log('支持游戏功能');
        }

        const xiaomi = new smartPhone('小米', 1999, '红色', '5.51inch');
        console.log(xiaomi);

4.4.2 class的类继承

        class Phone{
            // 构造方法
            constructor(brand,price){
                this.brand = brand;
                this.price = price;
            }

            // 父类成员属性
            call(){
                console.log('通话功能');
            }
        }

        class smartPhone extends Phone {
            // 构造方法
            constructor(brand, price, color, size){
                super(brand,price);
                this.color = color;
                this.size = size;
            }
            photo(){
                console.log('拍照功能');
            }
            game(){
                console.log('支持游戏功能');
            }
        }

        const xiaomi = new smartPhone('小米', 999, '黑色', '4.7inch');
        console.log(xiaomi);

4.5 子类对父类方法的重写

        class Phone{
            // 构造方法
            constructor(brand,price){
                this.brand = brand;
                this.price = price;
            }

            // 父类成员属性
            call(){
                console.log('通话功能');
            }
        }

        class smartPhone extends Phone {
            // 构造方法
            constructor(brand, price, color, size){
                super(brand,price);
                this.color = color;
                this.size = size;
            }
            photo(){
                console.log('拍照功能');
            }
            game(){
                console.log('支持游戏功能');
            }
            // 子类对父类方法重写
            call(){
                console.log('视频通话功能');
            }
        }

        const xiaomi = new smartPhone('小米', 999, '黑色', '4.7inch');
        xiaomi.call();

4.6 class中的getter和setter设置

        // get 和 set
        class Phone{
            get price(){
                console.log('价格属性被读取了');
                return '价格';
            }
            
            set price(newVal){
                console.log('价格属性被修改了');
            }
        }

        let s = new Phone();
        // console.log(s.price);
        s.price = 'free';

五、ES6的数值扩展

5.1 Number.EPSILON

Number.EPSILON 是 JavaScript 表示最小精度

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16

一般应用于浮点数运算

        function equal(a,b){
            if(Math.abs(a-b) < Number.EPSILON){
                return true;
            } else {
                return false;
            }
        }
        console.log(0.1 + 0.2 === 0.3);
        console.log(equal(0.1 + 0.2, 0.3));

5.2 二进制和八进制

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示

十六进制:0x

        let b = 0b1010; // 二进制
        let o = 0o777; // 八进制
        let d = 100; // 十进制
        let x = 0xff; // 十六进制
        console.log(b);
        console.log(o);
        console.log(d);
        console.log(x);

5.3 Number.isFinite() 与 Number.isNaN()

Number.isFinite() 检测一个数值是否为有限数

        console.log(Number.isFinite(100));
        console.log(Number.isFinite(100/0));
        console.log(Number.isFinite(Infinity));

Number.isNaN() 检测一个数值是否为NaN

        console.log(Number.isNaN(123));

5.4 Number.parseInt() 与 Number.parseFloat()

Number.parseInt() 与 Number.parseFloat() 字符串转整数

        console.log(Number.parseInt('4564321aasdsd'));
        console.log(Number.parseFloat('3.15462184asdasd'));

ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用方式不变

5.5 Number.isInteger()

Number.isInteger() 判断一个数是否为整数

        console.log(Number.isInteger(12));
        console.log(Number.isInteger(1.2));

5.6 Math.trunc()

Math.trunc() 用于将数字的小数部分抹掉

        console.log(Math.trunc(3.14));

5.7 Math.sign()

Math.sign() 用于判断一个数到底为正数、负数 还是 零

        console.log(Math.sign(100));
        console.log(Math.sign(0));
        console.log(Math.sign(-100));

六、ES6的对象方法扩展

6.1 Object.is()

Object.is() 用于判断两个值是否完全相等,与( === )行为基本一致,但在NaN的比较上有区别

        console.log(Object.is(10,11));  // false
        console.log(Object.is(10,10));  // true
        console.log(Object.is(NaN,NaN));  // true
        console.log(NaN === NaN);  // false

6.2 Object.assign()

Object.assign(object1, object2) 用于对象的合并

注意:

  1. 对象中相同名称的属性,object2 会覆盖 object1
  2. 如果 object1 含有 object2 中含有的属性,则以 object1 中为准
        const server1 = {
            host: 'localhost',
            port: 8000,
            name: 'root',
            pass: 'root',
            test: 'test'
        }

        const server2 = {
            host: 'http://127.0.0.1',
            port: 8080,
            name: 'admin',
            pass: 'admin',
            test2: 'test2'
        }
        console.log(Object.assign(server1, server2));

6.3  setPrototypeOf()、setPrototypeOf() 

setPrototypeOf()、setPrototypeOf() 用于直接设置对象的原型

        const person = {
            name: '王小明'
        }
        const skill = {
            jineng: ['唱歌','跳舞','钢琴']
        }
        // 并不建议采用这种方法设置对象原型
        Object.setPrototypeOf(person, skill);
        console.log(Object.getPrototypeOf(person));
        console.log(person);

七、模块化

7.1 模块化介绍

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

7.1.1 模块化的好处

  1. 防止命名冲突
  2. 代码复用
  3. 高维护性

7.1.2 模块化规范产品

ES6之前的模块化规范:

  1. CommonJS => NodeJS、Browserify
  2. AMD => requireJS
  3. CMD => seaJS

7.2 ES6模块化语法

模块功能主要由两个命令构成:export 和 import

  • export 命令用于规定模块的对外接口
  • import 命令用于输入其他模块提供的功能

m1.js(导出模块)

export let person = '周星星';

export function movie(){
    console.log('会指导电影拍摄');
}

简单模块化使用.html(导入和使用模块)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module">
        // 引入 m1.js 模块内容
        import * as m1 from './js/m1.js';
        console.log(m1);
    </script>
</body>
</html>

7.3 ES6暴露(导出)数据语法汇总

7.3.1 逐个导出模块

m1.js

// 分别暴露(导出)
export let person = '周星星';

export function movie(){
    console.log('会指导电影拍摄');
}

7.3.2 统一导出模块

m2.js

// 统一暴露(导出)
let person = '周星星';

function sing(){
    console.log('会唱歌');
}

export {person, sing};

7.3.3 默认导出模块

m3.js

// 默认暴露(导出)
export default {
    person: 'JOJO',
    boxing: function(){
        console.log('会拳击');
    }
}

注意:默认导出模块的语法,在需要调用该模块内容时需要添加default

    <script type="module">
        // 引入 m1.js 模块内容(分别导出)
        import * as m1 from './js/m1.js';
        // 引入 m2.js 模块内容(统一导出)
        import * as m2 from './js/m2.js';
        // 引入 m3.js 模块内容(默认导出)
        import * as m3 from './js/m3.js';
        // console.log(m3);
        m3.default.boxing();
    </script>

7.4 ES6引入数据语法汇总

7.4.1 通用的导入方式

        // 1. 通用的导入方式
        // 引入 m1.js 模块内容(分别导出)
        import * as m1 from './js/m1.js';
        // 引入 m2.js 模块内容(统一导出)
        import * as m2 from './js/m2.js';
        // 引入 m3.js 模块内容(默认导出)
        import * as m3 from './js/m3.js';

7.4.2 解构赋值形式

注意:

  • 属性重名时,可以采用 as 设置别名
  • 遇到默认导出模块语法时,需要采用 as 设置别名
        // 2. 解构赋值形式
        import {person, movie} from './js/m1.js';
        import {person as people, sing} from './js/m2.js';
        import {default as m3} from './js/m3.js';

7.4.3 简便形式(针对默认导出语法)

        // 3. 简便形式  针对默认暴露(导出)
        import m3 from './js/m3.js';

7.5 浏览器使用ES6模块化方式二

script标签 src 属性引入相关文件,将 js 语法整合到一个文件app.js

<script src="./js/app.js" type="module"></script>

app.js

// 入口文件

// 模块引入
import * as m1 from './m1.js';
import * as m2 from './m2.js';
import * as m3 from './m3.js';

console.log(m1);
console.log(m2);
console.log(m3);

7.6 babel对ES6模块化代码转化

Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器 (babeljs.cn)icon-default.png?t=M276https://www.babeljs.cn/Babel 是一个 JavaScript 编译器

Babel 能够将新的ES规范语法转换成ES5的语法

因为不是所有的浏览器都支持最新的ES规范,所以,一般项目中都需要使用Babel进行转换

步骤:

  1. 使用Babel转换JS代码
  2. 打包成一个文件
  3. 使用时引入即可

7.6.1 步骤

1)安装工具babel-cli(命令行工具) babel-preset-env(ES转换工具) browserify(打包工具, 项目中使用的是(webpack)

2)初始化项目

npm init --yes

3)安装相关工具

npm i babel-cli babel-preset-env browserify
npm i(i 是 install缩写) babel-cli babel-preset-env browserify -D(这样安装是局部安装)

注意:用npm i安装的模块无法用npm uninstall删除,用npm uninstall i才卸载掉 

4)使用babel转化

npx babel js(js目录) -d dist/js(转化后的js目录)
npx babel js(js目录) -d dist/js(转化后的js目录) --presets=babel-preset-env(命令行传参)

5)打包

npx browserify dist/js/app.js -o dist/bundle.js

6)在使用时引入bundle.js

    <script src="dist/bundle.js" type="module"></script>

7)注意:如果后续有修改,需要重新使用babel转化,再重新打包

八、ES6模块化引入NPM包

8.1 安装

以jquery为例

npm i jquery
npm i (npm包)

8.2 导入

以jquery为例

import $ from 'jquery'; // 与 const $ = require('jquery'); 功能一样
import $ from 'npm包名';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JHY97

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值