记录一些 ECMAScript 笔记

344 阅读1分钟

ECMAScript 6

变量解构
ES6 允许按照一定的模式从数组和队形中提取值,对变量进行赋值,这被称为解构赋值。
1.数组的解构
const array = ['张三', '李四', '王五', '赵六'];
let [name1, name2, name3, name4] = array;
2.对象的解构
const array = {
    name: '张三',
    age: 20,
    jsTest: function() {
        sonsole.log('Hello world');
    }
}
let {name, age, jsTest} = array;
//也可以单独解构
let {jsTest} = array;
模板字符串
ES6 引入新的声明字符串的方式 `` '' ""
1.声明
let str = `我也是一个字符串`;
2.内容中可以直接出现换行符
let str = `
	我
	是
	子
	符
	串
`;
3.变量拼接
let name = '张三';
let str = `${name}早上好!`;
对象的简化写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
let name = '张三';
let change = function() {
    console.log("Hello world");
}
const data = {
    name,
    change,
    jsTest() {
        console.log("Hello world");
    }
}
箭头函数
ES6 允许使用【箭头】 => ()定义函数
//声明函数
let jsTest = (a, b) => {
    return a + b;
}
//调用函数
let result = jsTest(1, 2);
console.log(result);

普通函数与箭头函数的区别:
1.this是静态的,this始终是指向函数声明是所在作用域下的this的值
2.不能作为构造实例化对象
3.不能使用arguments变量
4.箭头函数的简写 - 省略小括号,当形参只有一条语句的时候; 省略花括号,当代码只有一条语句的时候
函数参数的默认值设置
ES6 允许给函数参数赋值初始化 
1.形参初始值 具有默认值的参数,一般位置要靠后(潜规则)
function jsTest(a, b, c = 100) {
    return a + b + c;
}
let result = jsTest(1, 2);
console.log(result);
2.与解构赋值结合
function jsTest({a = 100, b, c}) {
    console.log(a);
    console.log(b);
    console.log(c);
}
jsTest({
    b: 5,
    c: 10
})
console.log(result);
Rest 参数
ES6 引入 rest 参数,用于获取函数的实参,来代替 arguments
//rest参数必须要放到最后
 function jsTest(a, b, ...args) {
     console.log(a);
     console.log(b);
     console.log(args);
 }
jsTest(1, 2, 'a', 'b', 'c');
扩展运算符
... 扩展运算符能够将数组转换为逗号分隔的参数序列
//声明一个数组 
const array = ['a', 'b', 'c', 'd'];
//声明一个函数
function jsTest() {
    console.log(arguments);
}
jsTest(...array);
Symbol数据类型
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的类型。
Symbol 特点
1.Symbol的值是唯一的,用来解决命名冲突的问题
2.Symbol值不能与其他数据进行运算
3.Symbol定义的对象属性不能使用for...in循环遍历,但可以使用Reflect.ownKeys来获取对象的所有键名
//创建Symbol
let s = Symbol();
//Symbol.for 创建
let s1 = Symbol.for('张三');
let s1 = Symbol.for('张三');
//不能与其他数据进行运算
迭代器
迭代器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成变量操作。
1.ES6创建了一种新的变量命令 for...of循环,Iterator接口主要供for...of写法
//声明一个数组
const array = ['a', 'b', 'c', 'd'];
//使用for...of变量数组
for (let val of array) {
    console.log(val);
}
//使用for...in变量数组
for (let val in array) {
    console.log(val);
}
2.原始具备Iterator接口的数据(可用for of遍历)
	a).Array
    b).Arguments
    c).Set
    d).Map
    e).String
    f).TypedArray
    g).NodeList
3.工作原理
	a).创建一个指针对象,指向当前数据结构的起始位置
    b).第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    c).接下来不断调用next方法,指针一直往后移动,知道指向最后一个成员
    d).每调用next方法返回一个包含value和done属性的对象
let iterator = array[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
生成器
生成器函数是ES6提供的一种异步变成解决方案,语法行为与传统函数不同
//生成器其实就是一个特殊的函数
//异步编程 纯回调函数
//函数代码的分割符
function* jsTest() {
    console.log("Hello world1");
    yield '今天真晴朗1';
    console.log("Hello world1");
    yield '今天真晴朗2';
    console.log("Hello world1");
    yield '今天真晴朗3';
    console.log("Hello world1");
}
let iterator = jsTest();
iterator.next();
//变量
for (let val of jsTest()) {
    console.log(val);
}

/** 生成器函数参数 */
 function* jsTest(arg) {
     console.log(arg);
     let one = yield '今天真晴朗1';
     console.log(one);
     let two = yield '今天真晴朗2';
     console.log(two);
     let three = yield '今天真晴朗3';
     console.log(three);
 }
//执行获取迭代器对象
let iterator = jsTest('AAA');
console.log(iterator.next());
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
Promise
PromiseES6引入的异步变成的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或者失败的结果。
1.Promise构造函数:Promise(excutor){}
2.Promise.prototype.then 方法
3.Promise.prototype.catch 方法
//实例化 Promise 对象
const promise = new Promise(function (resolve, reject) {
   setTimeout(() => {
       //成功
       // let data = '我是一些数据成功';
       // resolve(data);
       //失败
       let err = '我是一些数据失败';
       reject(err);
   }, 1000);
});
//调用 Promise 对象的 then 方法
promise.then(function (value) {
   console.log(value);
}, function (reason) {
   console.log(reason);
});


/** 案例(Promise封装AJAX请求) */
//接口地址:https://api.apiopen.top/getJoke
const promise = new Promise((resolve, reject) => {
   //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) {
               //表示成功
               resolve(xhr.response)
           } else {
               //如果失败
               reject(xhr.status);
           }
       }
   }
});
//指定回调
promise.then(function (value) {
   console.log(value);
}, function (reason) {
   console.log(reason);
});
Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,单成员的值都是唯一的,集合实现了iterator接口,所以可以使用“扩展运算符”和“for...of...”进行遍历。
Set的属性和方法:
1.size	返回集合的元素个数
2.add	增加一个新元素,返回当前集合
3.delete删除元素,返回boolean值
4.has	监测集合中是否包含某个元素,返回boolean值
//声明一个set
let s = new Set();
let s2 = new Set(['a', 'b', 'c', 'a']);
Map
ES6 提供了 Map 数据结构。它类似与对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所有可以使用“扩展运算符”和“for...of...”进行遍历。
Map的属性和方法:
1.size	返回集合的元素个数
2.add	增加一个新元素,返回当前集合
3.delete删除元素,返回boolean值
4.has	监测集合中是否包含某个元素,返回boolean值
5.clear	清空集合,返回undefined
//声明一个Map
let m = new Map();  
class 类
ES6 提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6class可以看作知识一个语法,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
知识点:
1.class声明类
2.constructor定义构造函数初始化
3.extends调用父级构造方法
4.super调用父级构造方法
5.static定义静态方法和属性
6.父类方法可以重写

ECMAScript 7

Array.prototype.includes
includes 方法用来检测数组中是否包含某个元素,返回波尔类型值
//includes
const dataArray = ['a', 'b', 'c', 'd'];
//判断
console.log(dataArray.includes('a'));
console.log(dataArray.includes('e'));
// **幂运算 2 ** 10 = Math.pow(2, 10)是相等的
console.log(2 ** 10);
console.log(Math.pow(2, 10));

ECMAScript 8

async 和 await
asyncawait 两种语法结合可以让异步代码像同步代码一样。
1.async 函数
	a).aysnc 函数的返回值为 promise 对象
    b).promise 对象的结果由 asycn 函数执行的返回值决定
//async 函数
async function jsTest() {
    //返回的结果不是一个 Promise 类型的对象 返回的结果就是成功Promise对象
    // return;
    //抛出错误,返回的结果是一个失败的Promise
    // throw new Error('出错了');
    //返回的结果如果是一个Promise对象
    return new Promise((resolve, reject) => {
        //成功的数据
        resolve('成功');
        //失败的数据
        // reject('失败');
    })
}
const result = jsTest();
//调用then方法
result.then(value => {
    console.log(value);
}, reason => {
    console.log(result);
});

2.await 表达式
	a).await 必须写在 async 函数中
    b).await 右侧的表达式一般为 promise 对象
    c).await 返回的是 promise 成功的值
    d).await 的 promise 失败了,就会抛出异常,需要通过try...catch捕获处理
//创建 promise 对象
const promise = new Promise((resolve, reject) => {
    resolve('成功');
});
//await 要放在 async 函数中
async function jsTest() {
    let result = await promise;
    console.log(result);
}
//调用函数
jsTest();
对象方法的扩展
Object.values 、 Object.entries、Object.getOwnPropertyDescriptors
1.Object.values() 方法返回一个给定对象的所有可枚举属性值的数组
2.Object.entries() 方法返回一个给定对象自身可遍历属性 [key, value] 的数组
3.Object.getOwnPropertyDescriptors 该方法返回指定对象所有自身属性的描述对象
//声明对象
const user = {
    name: '张三',
    array: ['a', 'b', 'c', 'd']
}
//获取对象所有的键
console.log(Object.keys(user));
//获取对象所有的值
console.log(Object.values(user));
//entries
console.log(Object.entries(user));
//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(user));

ECMAScript 9

对象展开
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,
在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
function jsTest({ val1, val2, ...val }) {
    console.log(val1);
    console.log(val2);
    console.log(val);
}
jsTest({
    val1: 'a',
    val2: 'b',
    val3: 'c',
    val4: 'd'
});
正则扩展 - 命名捕获分组
//声明一个字符串
let str = '<span value="world">Hello</span>';
//提取 value 与 【标签文本】
const reg = /<span value="(.*)">(.*)<\/span>/;
//执行
const result = reg.exec(str);
console.log(result);
正则扩展 - 反向断言
 //声明字符串
let str = '11111略略略2222啦啦啦33333你好';
//正向断言
const reg = /\d+(?=你好)/;
const result = reg.exec(str);
//反向断言
const reg = /(?<=啦)\d+/;
const result = reg.exec(str);
console.log(result);

ECMAScript 10

Object.fromEntries
Object.fromEntriesES8 中的Object.entries区别是
Object.fromEntries 是将二维数组转换为对象
ES8 中的Object.entries 是将对象转换为二维数组
//二维数组
const result = Object.fromEntries(
    [
        ['name', '张三'],
        ['age', '20']
    ]
);
//Map
const map = new Map();
map.set('name', '张三');
const result = Object.fromEntries(map);
console.log(result);
字符串的两个扩展方法 trimStart 与 trimEnd
trimStart 是去除字符串左侧空白
trimEnd 是去除字符串右侧空白
//trim
let str = "     hello world   ";
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
数组的两个方法 flat 与 flatMap
//flat 
//将多维数组转换为低维数组
const arr = [1, 2, 3, 4, [[5, 6], 7, 8, 9], 10];
//参数为深度 默认值为 1
console.log(arr.flat(2));

//flatMap 
//把Map的结果进行维度降低
const arr = [1, 2, 3, 4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);
Symbol 的扩展 Symbol.prototype.description
//用来获取Symbol的字符串描述
 //创建 Symbol
let s = Symbol('张三');
console.log(s.description);

ECMAScript 11

私有属性
class Person {
    //公有属性
    name;
    //私有属性
    #age;
    #weight;
    //构造方法
    constructor(name, age, weight) {
        this.name = name;
        this.#age = age;
        this.#weight = weight;
    }
}
//实例化
const user = new Person('张三', 20, '50kg');
console.log(user);
console.log(user.name);
console.log(user.#age);
console.log(user.#weight);
Promise.allSettled
// 这个方法它接收一个Promise数组,返回的是一个Promise对象,返回的状态永远是成功的。

// 示例
const p1 = new Promise((resolve, reject) => {
   	setTimeout(() => {
        resolve('成功了 - 1');
    }, 1000); 
});

const p2 = new Promise((resolve, reject) => {
   	setTimeout(() => {
      	resolve('成功了 - 2')  
    });
});

const result = Promise.allSetted([p1, p2]);

// 与Promise.all的区别是,all方法中是根据每个对象中的状态进行判断的,如果说其中有一个失败,那就是失败的。
字符串扩展 String.prototype.matchAll
const str = `http://localhost:3000?id=1&name=略略略&age=20`;

// 创建正则
const reg = /\?id=(.*?)&name=(.*?)&age=(.*?)$/sg;

const result = str.matchAll(reg);

for (let value of result) {
	console.log(value);
}
可选链操作符
// ?.
// 即便没有传入对象也不会报错
const user = {
    name: '略略略',
    action: {
        sing: '唱',
        jump: '跳'
    }
}

function jsTest(user) {
    const result = user?.action?.sing;
    console.log(result);
}

jsTest(user);
动态import
// 在需要用到的时候导入
// 获取元素
const btn = document.getElemntById('btn');

btn.onclick = function() {
    import('./hello.js').then(module => {
       module.hello(); 
    });
}
新的数据类型 BigInt
// 大整形 BigInt
let n = 500n;

console.log(n, typeof(n));

// 函数
let n = 123;
console.log(BigInt(n));		//转换数据类型

// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(BigInt(max) + 1);		// 报错,不能直接和普通数据类型进行运算
console.log(BigInt(max) + BigInt(1));	//这样才可以
全局this globalThis
// globalThis始终指向全局对象

console.log(globalThis);