ES6-11

2022-04-25 18:58:54 浏览数 (1)

ES6

let

  • 变量声明不能重复。
代码语言:javascript复制
let star = 'jay';
let star = 'chou';  // error
  • 块级作用域 全局 函数 eval
代码语言:javascript复制
{
    let girl = 'si';
}
console.log(girl);   // error
  • 不存在变量提升
代码语言:javascript复制
console.log(song);   // undefined
var song = 'song';
代码语言:javascript复制
console.log(song);   // error
let song = 'song';
  • 不影响作用域链
代码语言:javascript复制
{
    let school = 'clyz';
    function fn() {
        console.log(school)
    }
    fn();
}

const

  • 声明常量 一般大写
代码语言:javascript复制
const SCHOOL = 'CLYZ';
console.log(SCHOOL);   // 'CLYZ'
  • 必须有初始值
代码语言:javascript复制
const A;    // error
  • 常量的值不能修改
代码语言:javascript复制
SCHOOL = 'YLZX';   // error
  • 块级作用域
代码语言:javascript复制
{
    const PLAYER = 'UZI';
}
  • 对于数组和对象的元素修改,不算做对常量的修改,不会报错(引用类型)
代码语言:javascript复制
const TEAM = ['UZI', 'MXLG', 'Ming', 'Letme'];
TEAM.push('Meiko');

解构赋值

代码语言:javascript复制
const F4 = ['a', 'b', 'c', 'd'];
let [e, f, g, h] = F4;

console.log(e);   // 'a'
console.log(f);   // 'b'
console.log(g);   // 'c'
console.log(h);   // 'd'
  • 对象的解构赋值
代码语言:javascript复制
const zhao = {
    name: '赵本山',
    age: '50',
    xiaopin: function() {
        console.log('I can play xiaopin');
    }
};

let {name, age, xiaopin} = zhao;

console.log(name);   // '赵本山'

xiaopin();   // 'I can play xiaopin'

模板字符串

  • 声明
代码语言:javascript复制
let str = `I am a string`;
  • 内容中可以出现换行符
代码语言:javascript复制
let str = `<ul>
			<li>aaa</li>
		  </ul>
		  <ul>
    		<li>aaa</li>
		  </ul>`
  • 变量拼接
代码语言:javascript复制
let a = '123';
let b = '456';
let out = `${a}---${b}`;    // '123---456'

简化对象写法

代码语言:javascript复制
let name = 'chen';
let change = function() {
    console.log('We can change you');
}

const SCHOOL = {
    name,     // equals  name: name
    change,   // equals  change: change
    improve() {   // equals  improve: function() { return }
        return
    }
}

箭头函数

代码语言:javascript复制
let fn = function(a, b) {
    return a   b;
}

let fn = (a, b) => {
    return a   b;
}
  • 箭头函数的this是静态的,始终指向函数声明时所在作用域,不受call、apply等改变
代码语言:javascript复制
function getName() {
    console.log(this.name);
}

let getName2 = () => {
    console.log(this.name);
}

window.name = 'chen';

const school = {
    name: 'chenshuai';
}

// 直接调用
getName();    // 'chen'
getName2();   // 'chen'

// call 方法调用
getName.call(school);     // 'chenshuai' 
getName2.call(school);    // 'chen'
  • 箭头函数不能作为构造器实例化对象
代码语言:javascript复制
let Person = (name, age) => {
    this.name = name;
    this.age = age;
}

let me = new Person('chen', 23);

console.log(me);    // error
  • 不能使用arguments变量
代码语言:javascript复制
let fn = () => {
    console.log(arguments);
}

fn(1, 2, 3);    // error
  • 箭头函数的简写
代码语言:javascript复制
let add = (n) => { return n   1 };

// 1. 当形参有且只有1个时可以省略参数体处的小括号
let add = n => { return n   1 };

// 2. 当形参有且只有1个时可以省略方法体处的花括号
// 此时 return 必须省略,并且执行结果就是函数返回值
let add = n => n   1;
  • 剪头函数适合与this无关的回调、定时器、数组方法,不适合与this有关的回调、dom事件回调、对象的方法
代码语言:javascript复制
// 获取元素
let ad = document.getElementById('ad');

// 绑定事件
ad.addEventListener('click', function() {
    // 保存外层this值供内部使用
    let _that = this;
    
    setTimeOut(function() {
        this.style.background = 'pink';
        // background is undefined
        console.log(this);
        // Window
    }, 2000);
    
    setTimeOut(() => {
        this.style.background = 'pink';
        console.log(this);     // ad
    }, 2000);
})
代码语言:javascript复制
const arr = [1, 6, 9, 10, 100, 123];

const result = arr.filter(function(item) {
    if(item % 2 === 0) {
        return true;
    } else {
        return false;
    }
})

console.log(result);   // [6, 10, 100]

--------------------------------------------------------
    
const result = arr.filter(item => item % 2 === 0);

console.log(result);   // [6, 10, 100]
  • 函数默认参数
代码语言:javascript复制
// 1. 形参初始值,具有默认值的参数位置一般靠后
function add(a, b, c) {
    return a   b   c;
}

add(1, 2, 3);    // 6
add(1, 2);       // NaN

function add3(a, b, c = 10) {
    return a   b   c;
}

add3(1, 2, 3);    // 6
add3(1, 2);       // 13

// 2. 与解构赋值结合
function connect(options) {};

connect({
    host: 'localhost',
    username: 'root',
    password: 'pwd',
    // port: 3306
})

function connect({host, username, password = 'root', port = 3306) {
	console.log(host);       // 'localhost'
	console.log(password);   // 'root'
	console.log(port);       // 3306
}

rest参数

  • 用于获取函数实参,代替arguments
代码语言:javascript复制
function data() {
    console.log(arguments);
}

data(1, 2, 3);   // Arguments(3) [1, 2, 3]

function data2(...args) {
    console.log(args);   // filter some array map
}

data2(1, 2, 3);   // [1, 2, 3]

// rest 参数必须放在最后
function fn(a, b, ...args) {
    console.log(a);
    console.log(b);
    console.log(args);
}

fn(1, 2, 3, 4, 5, 6);
// 1
// 2
// [3, 4, 5, 6]

扩展运算符

代码语言:javascript复制
const tfboys = ['易烊千玺', '王俊凯', '王源'];

function chunwan() {
    console.log(arguments);
}

chunwan(tfboys);   // ['易烊千玺', '王俊凯', '王源']
chunwan(...tfboys);   // { 0:'易烊千玺', 1:'王俊凯', 2:'王源'}
  • 数组合并
代码语言:javascript复制
const arr = [1, 2, 3];
const arr2 = ['a', 'b', 'c'];

const _arr = arr.concat(arr2);   // [1, 2, 3, 'a', 'b', 'c']

const _arr2 = [...arr, ...arr2]; // [1, 2, 3, 'a', 'b', 'c']
  • 数组克隆
代码语言:javascript复制
const arr = ['E', 'G', 'M'];
const _arr = [...arr];     // ['E', 'G', 'M']
  • 将伪转为数组
代码语言:javascript复制
const divs = document.querySelectorAll('div');
const divArr = [...divs];   // [div, div, div]

Symbol

  • es6引入的第七种原始数据类型,是一种类似字符串的类型,表示独一无二的值
  1. Symbol 的值是唯一的,可以用于解决命名冲突的问题;
  2. Symbol 的值不能与其他数据进行运算;
  3. Symbol 定义的对象属性不能使用 for...in...循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名;
代码语言:javascript复制
// 1. 创建 Symbol,内部实现唯一性,外部不显示
let s = Symbol();
console.log(s, typeof s);   // Symbol()   'symbol'

// 2. 内部可以传入一个标识
let s2 = Symbol('s');
let s3 = Symbol('s');

console.log(s2 === s3);     // false

// 3. 通过 Symbol.for 创建
let s4 = Symbol.for('s');
let s5 = Symbol.for('s');

console.log(s4 === s5);     // true

// 4. 不能与其他数据进行运算
let result = s   100;    // error
let result = s > 100;    // error
let result = s   '100';  // error
  • Symbol 创建对象属性
代码语言:javascript复制
// 使用 Symbol 向对象中添加方法
let game = {
    name: '贪吃蛇'
};

let methods = {
    up: Symbol();
    down: Symbol();
}

game[methods.up] = function() {
    console.log('up');
}

game[methods.down] = function() {
    console.log('down');
}

console.log(game);

----------------------------------------------------

let game2 = {
    name: '狼人杀',
    [Symbol('say')]: function() {
        console.log('I can say');
    },
    [Symbol('boom')]: function() {
        console.log('I can boom');
    }
}

console.log(game2);
  • Symbol 内置值
代码语言:javascript复制
class Person {
    static [Symbol.hasInstance](param) {
        console.log('我被用来检测类型了');
        console.log(param);
    }
}

let o = {};

console.log(o instanceof Person);    // false

迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制

  1. es6 创造了一种新的遍历命令 for..of 循环,Iterator 主要供 for...of 消费
  2. 原生具备iterator接口的数据(可用 for...of 遍历)
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList
  3. 工作原理
    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
代码语言:javascript复制
coonst xyj = ['唐僧', '孙悟空', '猪八戒', '沙悟净'];

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

let iterator = xyj[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: '沙悟净', done: false }
console.log(iterator.next());   // { value: undefined, done: true }
  • 需要自定义遍历数据的时候要想到迭代器
代码语言:javascript复制
// 声明一个对象
const c = {
    name: '高一1班',
    students: ['liu', 'chen', 'wang']
}

// 遍历这个对象
for(let i of c) {
    console.log(i);  // c is not iterator
}

----------------------------------------------------

const d = {
    name: '高一1班',
    students: ['liu', 'chen', 'wang'],
    [Symbol.iterator]() {
        let index = 0;
        let _that = this;
    	return {
            next: function() {
            	if(index < _that.students.length) {
                    const result = {
                        value: _that.students[index],
                        done: false
                    };
                    index  ;
                    return result;
                } else {
                    return {
                        value: undefined,
                    	done: true
                    }
                }
            }
        };    
    }
}

for(let i of d) {
    console.log(i);
}
// 'liu'
// 'chen'
// 'wang'
// 'undefined'

生成器

  • 生成器函数(generator / yield)是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
代码语言:javascript复制
// 生成器其实就是一个特殊的函数(以前的异步就是纯回调函数)
function * gen() {
    console.log('hello generator');
}

let iterator = gen();

console.log(iterator);    // gen()
iterator.next();          // 'hello generator'
  • yield
代码语言:javascript复制
// 函数代码的分隔符
function * gen() {
    console.log('1');
    yield 'a';
    console.log('2');
    yield 'b';
    console.log('3');
    yield 'c';
    console.log('4');
}

let iterator = gen();

iterator.next();    // '1'
iterator.next();    // '2'
iterator.next();    // '3'
iterator.next();    // '4'

for(let v of fen()) {
    console.log(v);
}
// 'a'
// 'b'
// 'c'

console.log(iterator.next());    // { value: 'a', done: false }
console.log(iterator.next());    // { value: 'b', done: false }
console.log(iterator.next());    // { value: 'c', done: false }
console.log(iterator.next());    // { value: undefined, done: true }
  • 生成器函数参数
代码语言:javascript复制
// next 方法可以传入实参,该实参作为对应yield语句的返回结果
function * gen(args) {
    console.log(args);
    let one = yield 111;
    console.log(one);
    let two = yield 222;
    console.log(two);
    let three = yield 333;
    console.log(three);
}

let iterator = gen('AAA');

console.log(iterator.next());    
// AAA
// { value: 111, done: false }

console.log(iterator.next('BBB'));    
// BBB
// { value: 222, done: false }

console.log(iterator.next('CCC'));    
// CCC
// { value: 333, done: false }

console.log(iterator.next('DDD'));    
// DDD
// { value: undefined, done: true }
  • 生成器函数实例
代码语言:javascript复制
// 异步编程 文件操作 网络操作 数据库操作
// 1s后输出111  2s后输入222  3s后输入333

// 回调地狱
setTimeOut(() => {
    console.log(111);
    setTimeOut(() => {
        console.log(222);
        setTimeOut(() => {
            console.log(333);
        }, 3000)
    }, 2000)
}, 1000)

// 生成器函数
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();    
// 111
// 222
// 333
代码语言:javascript复制
// 模拟获取 用户数据 订单数据 商品数据
function getUsers() {
    setTimeout(() => {
        let data = 'user data';
        // 调用 next 方法,并将数据传入
        iterator.next(data);
    }, 1000)
}

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

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

function * gen() {
    let users = yield getUsers();
    console.log(users);    // 'user data'
    let orders = yield getOrders();
    console.log(orders);    // 'order data'
    let goods = yield getGoods();
    console.log(goods);    // 'good data'
};

Promise

  • Promise 是ES6引入的异步编程的新解决方案,语法上Promise是一个构造函数。用来封装异步操作并获取其成功或失败的结果
    1. Promise构造函数: Promise(excutor) {}
    2. Promise.prototype.then() 方法
    3. Promise.prototype.catch() 方法
代码语言:javascript复制
// 实例化 Promise 对象
const p = new Promise(function(resolve, reject) {
    setTimeout(function() {
        if(Math.random() > 0.5) {
        	resolve('>')
        } else {
            reject('<')
        }
    }, 1000);
})

// 调用 Promise 的 then 方法
p.then(function(value) {
    console.log(value);
},
function(reason) {
    console.error(reason);
});
  • Promise 读取文件
代码语言:javascript复制
const fs = require('fs');

fs.readFile('./a.txt', (err, data) => {
    if(err) throw err;
    console.log(data);
});

//  使用 promise 封装
const p = new Promise(function(resolve, reject) {
    fs.readFile('./a.txt', (err, data) => {
        if(err) reject(err);
        resolve(data);
    });
});

p.then(function(value) {
    console.log(value.toString());
},
function(reason) {
    console.log('read faild');
});
  • Promise 封装 ajax
代码语言:javascript复制
const xhr = new XMLHttpRequest();

xhr.open('GET', 'https://localhost:8080/getToken');

xhr.send();

xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
        if(xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response);
        } else {
            console.error(xhr.status)
        }
    }
}

// 使用 Promise 封装
const p = new Promise((resolve, reject) => {
    xhr.open('GET', 'https://localhost:8080/getToken');

    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(function(value) {
	console.log(value);
},
function(reason) {
    console.log(reason);
});
  • Promise.prototype.then() 方法
代码语言:javascript复制
const p = new Promise((resolve, reject) => {
    setTimeout(function() {
        resolve('用户数据');
    });
})

// 调用then方法,返回结果是Promise对象,对象状态由回调函数的执行结果决定
// 1. 如果回调函数中返回的结果是非promise类型数据,状态为成功,返回值为对象的成功的值
// 2. 如果回调函数中返回的结果是promise类型数据

const result = p.then(value => {
    // 1. 返回非 promise 类型的属性
	// console.log(value);
    // return 'ok';
    
    // 2. 返回 promise 类型的属性
    return new Promise((resolve, reject) => {
        resolve('ok');
    })
    
    // 3. 抛出错误
    // throw new Error('出错了');
}, reason => {
    console.warn(reason);
});

console.log(p);    // Promise(...)


// 链式调用
p.then(value => {}, reason => {}).then(value => {});
  • Promise 读取多个文件
代码语言:javascript复制
const fs = require('fs');

fs.readFile('./a.txt', (err1, data1) => {
    fs.readFile('./b.txt', (err2, data2) => {
        fs.readFile('./c.txt', (err3, data3) => {
            let result = data1   'rn'   data2   'rn'   data3;
            console.log(result);
        });
    });
});

// 使用 promise
const p = new Promise((resolve, reject) => {
    fs.readFile('./a.txt', (err, data) => {
    	resolve(data);
    });
});

p.then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile('./b.txt', ), (err, data) => {
    		resolve([value, data]);
        };
    });
}).then(value => {
    fs.readFile('./c.txt', (err, data) => {
        value.push(data);
        resolve(value);
    });
}).then(value => {
    console.log(value.join('rn');
});
  • Promise.prototype.catch() 方法
代码语言:javascript复制
const p = new Promise((resolve, reject) => {
    setTimeout(function() {
        reject('出错了');
    });
});

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

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

Set

  • ES6提供了新的数据结构 Set(集合),它类似于数组,但成员的值都是唯一的,接口实现了iterator接口,因此可以使用扩展运算符和for...of进行遍历
  • 集合的属性和方法
    1. size 返回集合元素的个数
    2. add 新增一个元素,返回当前集合
    3. delete 删除元素,返回boolean值
    4. has 检测集合中是否包含某个元素,返回boolean值
代码语言:javascript复制
let s = new Set();
let s2 = new Set([1, 2, 3, 4, 1]);

console.log(s, typeof s);    // Set(0) {}    'object'
console.log(s2);             // Set(4) {1, 2, 3, 4}
console.log(s2.size);        // 4

s2.add(5);
console.log(s2);             // Set(5) {1, 2, 3, 4, 5}
console.log(s2.size);        // 5

s2.delete(1);
console.log(s2);             // Set(4) {2, 3, 4, 5}
console.log(s2.size);        // 4

console.log(s2.has(3));      // true
console.log(s2.has(6));      // false

s2.clear();
console.log(s2);             // Set(0) {}

for(let i of s2) {
    console.log(i);
}
// 1
// 2
// 3
// 4
  • Set实践
代码语言:javascript复制
// 1. 数组去重
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let result = [...new Set(arr)];    // [1, 2, 3, 4, 5]

// 2. 交集
let arr2 = [3, 4];
let result2 = [...new Set(arr)].filter(item => {
    let s2 = new Set(arr2);
    if(s2.has(item)) {
        return true;
    } else {
        return false;
    }
})

/* 简化 */
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));

// 3. 并集
let union = [...new Set([...arr, ...arr2])];

// 4. 差集(arr对arr2取差集)
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));

Map

  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,因此可以使用扩展运算符和for...of进行遍历
  • Map的属性和方法
    1. size 返回Map的元素个数
    2. set 新增一个元素,返回当前Map
    3. get 返回键名对象的键值
    4. has 检测Map中是否包含某个元素,返回boolean值
    5. clear 清空集合,返回undefined
代码语言:javascript复制
let m = new Map();
m.set('name', 'chenshuai');
m.set('change', function() {
    console.log('change');
});

let key = {
    token: 'md5'
};
m.set(key, 'nkghr458g674r8483434h');

Class

  • ES6提供了更接近传统语言的写法,引入类这个概念,作为对象的模板,通过class关键字可以定义类。基本上es的class可以看作只是一个语法糖,它的绝大部分功能es5都可以做到,新的class写法只是让对象原型的写法更清晰、更像面向对象编程的语法而已
  • 知识点
    1. class 声明类
    2. constructor 定义构造函数初始化
    3. extends 继承父类
    4. super 调用父级构造方法
    5. static 定义静态方法和属性
    6. 父类方法可以重写
代码语言:javascript复制
function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
}

Phone.prototype.call = function() {
    console.log('I can call');
}

let Huawei = new Phone('华为', 5999);
Huawei.call();         // 'I can call'

console.log(Huawei);   // { brand: '华为', price: 5999 }

// class 语法
class Phone {
    // 构造方法
    constructor(brand, price) {
    	this.brand = brand;
    	this.price = price;
    },
    call() {
        console.log('I can call');
    }
}

let onePlus = new Phone('1 ', 3999);

console.log(onePlus);   // { brand: '1 ', price: 3999 }
  • 类的静态成员
代码语言:javascript复制
// 实例对象与函数对象属性不相通
function Phone() {}


// 类的属性,不属于实例
Phone.name = 'name';
Phone.change = function() {
    console.log('I can change');
};

let nokia = new Phone();

console.log(nokia.name);     // undefined
nokia.change();              // nokia.change is mot a function

Phone.prototype.size = '5.5 inch';
console.log(nokia.size);     // '5.5 inch'
代码语言:javascript复制
class Phone {
    static name = '手机';
	static change() {
        console.log('I can change');
    }
}

let nokia = new Phone();
console.log(nokia.name);    // undefined
console.log(Phone.name);    // '手机'
  • 构造函数继承
代码语言:javascript复制
function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
}

Phone.prototype.call = function() {
    console.log('I can change');
}

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('I can take a photo');
}

SmartPhone.prototype.playGame = function() {
    console.log('I can play game');
}

const chuizi = new SmartPhone('锤子', 2499, 'black', '5.5 inch');
  • 类继承
代码语言:javascript复制
class Phone {
    constructor(brand, price) {
    	this.brand = brand;
    	this.price = price;
    }
    call() {
        console.log('I can call');
    }
}

class SmartPhone extends Phone {
    constructor(brand, price, color, size) {
        super(brand, price);
        this.color = color;
        this.size = size;
    }
    
    photo() {
       console.log('I can take a photo'); 
    }
    
    playGame() {
       console.log('I can play game'); 
    }
}

const xiaomi = new SmartPhone('小米', 3999, 'blcak', '5.8inch');

xiaomi.call();     // 'I can call'
xiaomi.photo();    // 'I can take a photo'
  • 子类对父类方法的重写
代码语言:javascript复制
class Phone {
    constructor(brand, price) {
    	this.brand = brand;
    	this.price = price;
    }
    call() {
        console.log('I can call');
    }
}

class SmartPhone extends Phone {
    constructor(brand, price, color, size) {
        super(brand, price);
        this.color = color;
        this.size = size;
    }
    
    photo() {
       console.log('I can take a photo'); 
    }
    
    playGame() {
       console.log('I can play game'); 
    }
    
    // 重写父类 call 方法
    call() {
        console.log('I can call with video');
    }
}

const xiaomi = new SmartPhone('小米', 3999, 'blcak', '5.8inch');

xiaomi.call();     // 'I can call with video'
  • get和set
代码语言:javascript复制
class Phone {
    get price() {
        console.log('get price');
        return 6688
    }
    
    set price(newVal) {
        console.log('set price:'   newVal);
    }
}

let s = new Phone();

console.log(s.price);    // 6688

s.price = 1688;

数值扩展

  • Number.EPSILON 是 js 表示的最小精度
代码语言:javascript复制
// 用于浮点数运算
console.log(0.1   0.2 === 0.3);    // false

function equal(a, b) {
    if(Math.abs(a - b) < Number.EPSILON) {
        return true;
    } else {
        return false;
    }
}

equal(0.1   0.2, 0.3);    // true
  • 二进制和八进制
代码语言:javascript复制
let b = 0b1010;
let o = 0o777;
let d = 100;
let x = 0xff;
  • Number.isFinite 检测一个数值是否为有限数
代码语言:javascript复制
console.log(Number.isFinite(100));           // true
console.log(Number.isFinite(100/0));         // flase
console.log(Number.isFinite(Infinity));      // false
  • Number.isNaN 检测一个数值是否为NaN
代码语言:javascript复制
console.log(Number.isNaN(123));              // false
  • Number.parseInt Number.parseFloat 字符串转数值
代码语言:javascript复制
console.log(Number.parseInt('5201314qs'));     // 5201314
console.log(Number.parseFloat('3.1415yzl'));   // 3.1415
  • Number.isInteger 判断一个数是否为整数
代码语言:javascript复制
console.log(Number.isInteger(5));          // true
console.log(Number.isInteger(2.5));        // false
  • Math.trunc 将数字的小数部分抹掉
代码语言:javascript复制
console.log(Math.trunc(2.5));              // 2
  • Math.sign 判断一个数是正数、负数、还是0
代码语言:javascript复制
console.log(Math.sign(100));               // 1
console.log(Math.sign(0));                 // 0
console.log(Math.sign(-99));               // -1

对象方法扩展

  1. Object.is 判断两个值是否完全相等
  2. Object.assign 对象的合并
  3. Object.setPrototypeOf 设置原型对象
  4. Object.getPrototypeOf
代码语言:javascript复制
// 1.
console.log(Object.is(NaN, NaN));    // true
console.log(NaN === NaN);            // false

// 2.
const conf1 = {
    host: '127.0.0.1',
    port: 3306,
    name: 'root',
    pass: 'root'
}

const conf2 = {
    host: 'localhost',
    port: 27017,
    name: 'admin',
    pass: 'admin'
}

console.log(Object.assign(conf1, conf2).host);   // 'localhost'

// 3.
const school = {
    name: 'sch'
}

const cities = {
    xiaoqu: ['bj', 'sh', 'sz'];
}

Object.setPrototypeOf(school, cities);

console.log(Object.getPrototypeOf(school));
console.log(school);

模块化

  • 好处
  1. 防止命名冲突
  2. 代码复用
  3. 高维护性
  • 产品
  1. CommonJS => NodeJS、Browserify
  2. AMD => requireJS
  3. CMD => seaJS
  • ES6模块化语法
  1. export 命令用于规定模块的对外接口
  2. import 命令用于输入其他模块提供的功能
代码语言:javascript复制
// main.js
// 分别暴露
export let name = 'chen';

export function skill() {
    console.log('my skill');
}

// 统一暴露
let name = 'chen';

function tech() {
    console.log('tech you');
}

export { school, tech() };

// 默认暴露
export default {
    name: 'chen',
    change: function() {
        console.log('change');
    }
}
代码语言:javascript复制
/* index.html */
<script type='module'>
    //引入 main.js
    import * as main from './main.js';
    
    m1.name;                // 'chen'
    m1.tech();              // 'tech you'
    m1.default.change();    // 'change'
</script>

<script type='module' src='./main.js'></script>
代码语言:javascript复制
// 1. 通用导入方式
import * as m1 from './m1.js';

// 2. 解构赋值形式
import { school, teach } from './m2.js';
import { school as clyz, teach } from './m2.js';
import { default as sch } from './m2.js';

// 3. 简写(针对默认暴露)
import m3 from './m3.js';
  • ES6 引入 npm 包
代码语言:javascript复制
// npm i jquery
// const $ = require('jquery');

import $ from 'jquery';
$('body').css('background', 'pink');

ES7

数组新增方法

  • Array.prototype.includes 监测数组中是否包含某个元素,返回布尔值
代码语言:javascript复制
const f4 = ['西游记', '红楼梦', '三国演义', '水浒传'];

f4.includes('西游记');    // true
f4.includes('金瓶梅');    // false
  • 指数操作符
代码语言:javascript复制
// equals Math.pow(2, 10);
console.log(2 ** 10);    // 1024

ES8

async和await

  • async和await两种语法结合可以让异步代码像同步代码一样
  • async函数
    1. async函数的返回值为promise对象
    2. promise对象的结果由async函数执行的返回值决定
  • await表达式
    1. await必须写在async函数中
    2. await右侧的表达式一般为promise对象
    3. await返回的是promise成功的值
    4. await的promise失败了会抛出异常,需要try...catch捕获处理
代码语言:javascript复制
async function fn() {
    // 返回字符串
    // 1. 返回的结果不是一个promise对象则函数返回的结果就会是一个成功的promise
    return 'abc';
    
    // 2. 抛出错误返回的结果是一个失败的promise
    throw new Error('error');
    
    // 3. 返回的结果是一个promise对象
    // async函数的返回值与该promise对象状态一致
    return new Promise((resolve, reject) => {
        resolve('success');
        // reject('faild');
    });
}

const result = fn();

console.log(result);   // Promise {...}

// 通过try...catch捕获异常
const p = new Promise((resolve, reject) => {
    resolve('ok');
    // reject('no');
})

async function main() {
    try {
        let result = await p;
        console.log(p);    // 'ok'
    } catch(e) {
        console.log(e);    // 'no'
    }
}
代码语言:javascript复制
// 使用promise读取文件
const fs = require('fs');

function read1() {
    return new Promise((resolve, reject) => {
        fs.readFile('./1.txt', (err, data) => {
            if(err) reject(err);
            resolve(data);
        })
    })
}

function read2() {
    return new Promise((resolve, reject) => {
        fs.readFile('./2.txt', (err, data) => {
            if(err) reject(err);
            resolve(data);
        })
    })
}

function read3() {
    return new Promise((resolve, reject) => {
        fs.readFile('./3.txt', (err, data) => {
            if(err) reject(err);
            resolve(data);
        })
    })
}

async function main() {
	let one = await read1();
	let two = await read2();
	let three = await read3();
    
    console.log(one);
    console.log(two);
    console.log(three);
}

main();

// 使用promise发送ajax请求
function sendAjax(url) {
    return new Promise((resolve, reject) => {
        const x = new XMLHttpRequest();
    
        x.open('GET', url);

        x.send();

        x.onreadystatechange = function() {
            if(x.readyState === 4) {
                if(x.statue >= 200 && x.status < 300) {
			   	   resolve(x.response);
                } else {
                    reject(x.status);
                }
            }
        }
    })
}

senAjax('https://xxx.com/token').then(value => {
    console.log(value);
});

// 使用async与await发送请求
async function main() {
    let result = await senAjax('https://xxx.com/token');
    console.log(result);
}

对象方法扩展

  • Object.values 和 Object.entries
    1. Object.values() 方法返回一个给定对象的所有可枚举属性值的数组
    2. Object.entries() 方法返回一个给定对象自身可遍历属性[k,v]的数组
代码语言:javascript复制
const school = {
    name: 'clyz',
    city: ['hn', 'zjj', 'cl']
}

// 获取所有键
Object.keys(school);      // ['name', 'city', 'sub']

// 获取所有值
Object.values(school);    // ['clyz', ['hn', 'zjj', 'cl']]

// entries
Object.entries(school);
// [['name', 'clyz'], ['city', ['hn', 'zjj', 'cl']]]
const m = new Map(Object.entries(school));

console.log(m);     // Map(3)
m.get('name');      // 'clyz'
  • Object.getOwnPropertyDescriptors 该方法返回指定对象所有自身属性的描述对象
代码语言:javascript复制
const obj = Object.create(null, {
    name: {
        value: 'clyz',
        writable: true,
        enumerable: true,
        configuarble: true
    }
})

Object.getOwnPropertyDescriptors(obj);
// { name: { value: 'clyz', writable: true, enumerable: true, configuarble: true }}

ES9

扩展运算符与rest参数

Rest 参数与 spread 扩展运算符在es6中已经引入,但仅限于数组,es9中为对象提供了像数组一样的 rest 参数和扩展运算符

代码语言:javascript复制
function connect(host, port, name, pass) {
    console.log(host);
    console.log(port);
    console.log(name);
    console.log(pass);
}

connect({
    host: '127.0.0.1',
    port: 3306,
    name: 'root',
    pass: 'root'
});

// use spread
function connect(host, port, ...user) {
    console.log(host);   // '127.0.0.1'
    console.log(port);   // 3306
    console.log(user);   // { name: 'root', pass: 'root' }
}

connect({
    host: '127.0.0.1',
    port: 3306,
    name: 'root',
    pass: 'root'
});
代码语言:javascript复制
const skill1 = {
    q: 'qqq'
}

const skill2 = {
    w: 'www'
}

const skill3 = {
    e: 'eee'
}

const skill4 = {
    r: 'rrr'
}

const ms = { ...skill1, ...skill2, ...skill3, ...skill4,};
// { q: 'qqq', w: 'www', e: 'eee', r: 'rrr' }

正则扩展

  • 命名捕获分组
代码语言:javascript复制
let str = '<a href="https://chen97.cn">匠新</a>';

// 提取 url 与标签文本
const reg = /<a href="(.*)">(.*)</a>/
const result = reg.exec(str);

-----------------------------------------------------------
    
let str = '<a href="https://chen97.cn">匠新</a>';

// 提取 url 与标签文本
const reg = /<a href="(?<url>.*)">(?<text>.*)</a>/
const result = reg.exec(str);     // groups
  • 反向断言
代码语言:javascript复制
let str = 'JS5201314你知道吗555哈哈哈';

// 正向断言
const reg = /d (?=啦)/;
reg.exec(str);    // '555'

// 反向断言
const reg = /(?<=么)d /;
reg.exec(str);    // '555'
  • dotAll 模式
代码语言:javascript复制
// dot . 元字符  除换行符外的任意单个字符
let str = `
	<ul>
		<li>
			<a>肖申克的救赎</a>
			<p>1997-09-10</p>
		</li>
		<li>
			<a>阿甘正传</a>
			<p>1997-07-06</p>
		</li>
	</ul>
`

const reg = /<li>s <a>(.*?)</a>s <p>(.*?)</p>/;
reg.exec(str);  // 0: <li>, 1: '肖申克的救赎', 2: '1997-09-10'

const reg2 = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/gs;
reg2.exec(str);

ES10

Object

  • Object.formEntries
代码语言:javascript复制
// 二维数组
const result = Object.formEntries([
    ['name': 'chenshuai'],
    ['age': 23]
])

// Map
const m = new Map();

m.set('name', 'chenshuai');

const result = Object.formEntries(m);

字符串

  • trimStart 与 trimEnd 清除字符串左侧和右侧的空格

数组

  • flat 和 flatMap 将多维数组转为低维数组
代码语言:javascript复制
const arr = [1,2,3,4,[5,6]];
const arr2 = [1,2,3,4,[5,6,[7,8,9]]];

arr.flat();     // [1,2,3,4,5,6]
arr2.flat();     // [1,2,3,4,5,6,[7,8,9]]
// 传入数字深度,默认1,使用 Infinity可展开任意深度的嵌套数组
arr2.flat(2);     // [1,2,3,4,5,6,7,8,9]
代码语言:javascript复制
const arr = [1,2,3,4];
const result = arr.map(item => item * 10);
// [[10],[20],[30],[40]]

const result = arr.flatMap(item => item * 10);
// [10,20,30,40]

Symbol

  • Symbol.prototype.description
代码语言:javascript复制
let s = Symbol('sys');

console.log(s.description);    // 'sys'

ES11

私有属性

代码语言:javascript复制
class Person {
    // 公有属性
    name;
    // 私有属性
    #age;
    #weight;
    // 构造方法
    constructor(name, age, weight) {
        this.name = name;
        this.#age = age;
        this.#weight = weight;
    }

	intro() {
        console.log(this.name);
        console.log(this.#age);
        console.log(this.#weight);
    }
}

// 实例化
const girl = new Person('jay', 18, '45kg');

girl.age;             // error
girl.intro();         // ...ok

Promise

  • Promise.allSettled
代码语言:javascript复制
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('goods1');
    }, 1000)
})

const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('error');
    }, 1000)
})

const result = Promise.allSettled([p1, p2]);
// Promise { pstatus: 'resolved', pvalue: [{ status: 'fulfilled', value: 'goods1'}, { status: 'rejected', value: 'error'}]}

const result = Promise.all([p1, p2]);
// Promise { pstatus: 'rejected', pvalue: 'error'}

String

  • String.prototype.matchAll
代码语言:javascript复制
let str = `
	<ul>
		<li>
			<a>肖申克的救赎</a>
			<p>1997-09-10</p>
		</li>
		<li>
			<a>阿甘正传</a>
			<p>1997-07-06</p>
		</li>
	</ul>
`

const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/gs;
const result = str.matchAll(reg);

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

const arr = [...result];

可选链操作符

代码语言:javascript复制
function main(config) {
    // const h = config && config.db && config.db.host;
    const h = config?.db?.host;
}

main({
    db: {
        host: '127.0.0.1',
        username: 'root'
    },
    cache: {
        host: '192.168.1.1',
        username: 'admin'
    }
});

动态 import

代码语言:javascript复制
// hello.js
export function hello() {
    console.log('hello');
}

// app.js
function fun() {
    import('./hello.js').then(modlue => {
        module.hello();
    });
}

BigInt 类型

代码语言:javascript复制
let n = 520n;
console.log(n, typeof n);       // 521n   'bigint'

let m = 123;
console.log(BigInt(m));       // 123n
console.log(BigInt(1.5));     // error

// 大数值运算
let max = Number.MAX_SAFE_INTEGER;

console.log(max);               // 9007199254740991
console.log(max   1);           // 9007199254740992
console.log(max   2);           // 9007199254740992

console.log(BigInt(max));               // 9007199254740991n
console.log(BigInt(max)   BigInt(1));   // 9007199254740992n
console.log(BigInt(max)   BigInt(2));   // 9007199254740993n

绝对全局对象 globalThis

代码语言:javascript复制
console.log(globalThis);     // window {...}

0 人点赞