说明

下面这些是根据视频教程加上个人理解写的笔记,仅代表个人理解!

水平不足,如有错误请批评指正!

image-20200718180806322

基础概念

  • ECMAScript

    ECMA (European Computer Manufacturers Association)中文名称为欧洲计算机制
    造商协,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际。

  • 版本迭代主要内容

    image-20200714120106607

  • 兼容性检查:http://kangax.github.io/compat-table/es6/

ES6新特性

let相关

不能重复声明
1
2
3
4
// 不能重复声明,var可以
let a = 'a'
let a = 'A'
// Uncaught SyntaxError: Identifier 'star' has already been declared
块级作用域

es5中的作用域:全局、函数、eval(严格模式下才会有,虽然我不懂严格模式是啥子)

let声明的是块级作用域,块外不能访问

1
2
3
4
5
{
let a = '333'
console.log(a, '1')
}
console.log(a, '2') // Uncaught ReferenceError: a is not defined
不存在变量提升

变量提升:https://www.jianshu.com/p/24973b9db51a

1
2
console.log(a);  //undefined,不会报错
var a = 123;
1
2
console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 'aaa'
不影响作用域链

image-20210125143858874

小案例-for循环使用let
1
2
3
4
5
6
7
8
let items = 'items是三个div的dom'
// 遍历并绑定事件
for(let i=0;i<items.length;i++){
items[i].onclick = functionn(){
this.style.background = 'pink'
items[i].style.background = 'pink' // var下回报错(报错原因i=3超出边界)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//使用var声明,得到3个3
var a = [];
for (var i = 0; i < 3; i++) {
a[i] = function () {
console.log(i);
};
}
a[0](); //3
a[1](); //3
a[2](); //3
//使用let声明,得到0,1,2
var a = [];
for (let i = 0; i < 3; i++) {
a[i] = function () {
console.log(i);
};
}
a[0](); //0
a[1](); //1
a[2](); //2

const–声明常量

  • 一定要赋初始值

  • 常量的值不能修改(引用地址不能修改)

  • 块级作用域

  • 对于数组和对象的元素修改,不算对常量的修改(引用地址没有修改)

    • 常使用const声明数组、对象
    1
    2
    3
    4
    const a = 1
    a = 2 // Uncaught TypeError: Assignment to constant variable
    const a = ['1','2','3']
    a.push('4') // 虽然对改变了数组a,但是a的地址并没有改变,所以没有问题

参考链接:https://www.cnblogs.com/minigrasshopper/p/9144223.htmlMDN说明

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动

对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针;

const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。

因此,将一个对象声明为常量必须非常小心。

数组解构和对象解构

  • 解构赋值:ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值
1
2
3
4
5
6
7
8
// 数组的解构赋值
const aaaa = ['一','二','三','四']
let [a,b,c,d] = aaaa // a='一',b='二'……
// 对象的解构赋值
const aa = {name:'yishen',age:18,school:'qinghua'}
let {name} = aa // yishen
let {age} = aa // 18
let {school} = aa // qinghua

模板字符串 ``

  • 内容中可以直接出现换行符号、’单引号’、”双引号”不行
  • 变量拼接
1
2
3
let love = '爱'
let str = `${love}你哦!`
console.log(str) // 爱你哦!

简化对象写法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,书写更简洁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let name = 'yishen'
let change = function(){
console.log('yishen')
}
const school = {
name:name,
change:chage,
improve:function(){
console.log('提升')
}
}
// 等价于
const school = {
name,
change,
improve(){
console.log('提升')
}
}

箭头函数 =>

1
2
3
4
5
6
let fn = function(a,b){
return a+b
}
let fn = (a,b) => { // 当参数有且只有一个参数,小括号可以省略
return a+b
}

参考链接:MDN-箭头函数this指向问题this指向问题

  • 箭头函数和普通函数区别

    • this是静态的(this始终指向函数声明时所在作用域下的this值)

    • ~~~javascript
      function getName(){
      console.log(this.name)
      }
      // 函数体内部只有一句,可以省略函数的花括号
      // 如果是return ,return必须省略,语句的执行结果就是函数的返回值
      let getName2 = () => console.log(this.name)
      // 设置window对象
      window.name = ‘yishen’
      const school = {
      name:’qinghua’
      }

      // 直接调用
      getName() // yishen
      getName2() // yishen
      // call 方法调用 call方法可以改变this的指向
      getName.call(school) // qinghua,this指向了school对象
      getName2.call(school) // yishen ,this执行依然是window(函数声明时所在作用域下的this)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21

      * 不能作为构造实例化对象

      ![image-20200714212647614](http://image.mdashen.com/pic/image-20200714212647614.png)

      `Uncaught TypeError:Person is not a constructor`

      * 不能使用 arguments 变量

      * 箭头函数适用范围
      * 箭头函数**适合**与this无关的回调。定时器,数组的方法回调
      * 箭头函数**不适合**于this无关的回调。事件回调,对象的方法

      #### 给函数参数赋初始值

      ##### 形参初始值

      ~~~JavaScript
      // 形参初始值,一般位置要靠后
      const add = (a,b,c=100)=> a+b+c
      add(1,2) // 103
与解构赋值结合
1
2
3
4
5
6
7
8
9
10
11
function connect({host='127.0.0.1',username,password,port=3306}){
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host:'mdashen.com',
username:'yishen',
password:'yishen'
})

rest参数

用于获取函数的实参,代替arguments

  • 传统arguments的使用
1
2
3
4
function date(){
console.log(arguments)
}
date('2','3','4') // arguments返回的是一个类数组对象,可以arguments[0]这样用
  • ES6新增,rest参数
1
2
3
4
5
6
7
// rest参数必须放到最后
function fu (a,b,...args){
console.log(a)
console.log(b)
console.log(args)
}
fn(1,2,3,4,5,6,7) // a=1,b=2,args=[3,4,5,6,7]

扩展运算符

扩展运算符能将 数组或对象 转换为逗号分隔的 参数序列

  • 数组合并
1
2
3
4
const a = [1,3,5]
const b = [2,4,6]
const c = a.concat(b) //[1, 3, 5, 2, 4, 6]
const d = [...a,...b] // [1, 3, 5, 2, 4, 6]

数据类型 Symbol

基本概念

ES6引入一种新的原始数组类型Symbol,表示独一无二的值

它是javascript语言的第七种数据类型,是一种类似于字符串的数组类型

  • Symbol特点
    • Symbol 的值是唯一的,用来解决命名冲容的问题
    • ymbol 值不能与其他数据进行运算
    • Symbol 定义的对象属性不能使用for.in 循环遍历,但是可以使用 Reflect. owners 来获取对象的所有键名
1
2
3
4
5
6
7
8
9
10
// 创建Symbol
let s = Symbol()
let s2 = Symbol('描述文字,相当于对这个变量的注释')
console.log(s, typeof s) // Symbol() "symbol"
console.log(s, typeof s2) // Symbol() "symbol"
console.log(Symbol('ddd')===Symbol('ddd')) // false
// Symbol.for创建
let s3 = Symbol.for('yishen')
let s4 = Symbol.for('yishen')
console.log(s3===s4) // true
  • 补充js中数据类型,7中基本数据类型+复杂数据类型object

USONB you are so niubility

u undefined

s string symbol

o object

n null number

b boolean BigInt

使用场景
  • 向对象中添加方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 方法一
let game = {
name:'俄罗斯方块',
up:function(){console.log('我是up方法')},
down:function(){console.log('我是down方法')}
}
let methods = {
up:Symbol(),
down:Symbol()
}
game[methods.up] = function(){
console.log('我也是up方法')
}
game[methods.down] = function(){
console.log('我也是down方法')
}
console.log(game) // 如下图

image-20200715123141141

  • 给对象添加方法——-方法二

image-20200715123622490

Symbol内置值

除了定义自己使用的Symbol值以外,ES6还提供了内置的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 环境排除。
  • 当o instanceof Person时,hasInstance方法会自动被调用

image-20200715140644214

  • 可自定义返回结果

image-20200715140751747

image-20200715141049908

迭代器

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

任何数据结构只要部署iterator接口(对象里面的一个属性Symbol.iterator),就可以完成遍历操作

  • ES6创造了一种新的遍历命令 for … of 循环,iterator接口主要供 for … of消费
  • 原生具备iterator接口的数据(可用for of 遍历)
    • Array、Arguments、Set、Map、String、TypedArray、NodeList
  • 工作原理
    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    • 每调用 next 方法返回一个包含 value 和 done 属性的对象
    • image-20200716074822000
    • 需要自定义遍历数据的时候,要想到迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 迭代器应用
const beijing = {
name: '终极一班',
stus: [
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator]() {
let index = 0
let _this = this
return {
next: function () {
if (index < _this.stus.length) {
const result = {value: _this.stus[index],done: false}
index++
return result
} else {
return { value: undefined,done: true}
}
}
}
}
}
for (const v of beijing) {
console.log(v) //xiaoming xiaoning xiaotian knight
}

生成器

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同

js的异步是单线程的

生成器的声明与调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function * gen(){
console.log(111)
yield 'yiele是代码的分割符1'
console.log(222)
yield 'yiele是代码的分割符2'
console.log(333)
yield 'yiele是代码的分割符3'
console.log(444)
}
let iterator = gen()
iterator.next() // 111
iterator.next() // 222

console.log(iterator.next()) // {value:'yiele是代码的分割符1',done:false}
console.log(iterator.next()) // {value:'yiele是代码的分割符2',done:false}
生成器的参数传递

image-20200716115523299

  • 生成器函数实例

image-20200716120633112

Promise

参考链接

Promise是ES6引入的异步编程的新解决方案。

语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

  • Promise构造函数:Promise(excutor){}
  • Promise.prototype.then()
  • Promise.prototype.catch()
    .then()返回的结果也是Promise对象,对象状态有回调函数的执行结果决定

.then().then()可以链式调用

数组结构 Set&Map

参考链接-菜鸟教程

Set

ES6提供了新的数据结构 Set(集合)。类似于数组,成员的值都是唯一的。

set实现了iterator接口,可以使用 扩展运算符for…of进行遍历

set的属性和方法

size 返回集合的元素个数
add 增加一个新元素,返回当前集合
delete 删除元素,返回boolean值
has 检测集合中是否包含某个元素,返回boolean值
clear 清空集合,返回undefined
1
2
3
4
5
6
// 声明集合set
let s = new Set(['1', 'er', 'san', 'si', 'san'])
console.log(s, typeof (s)) // Set(4){"1", "er", "san", "si"}"object"
// 集合会自动去重,可以利用这点做数组快速去重[...new Set(array)]
s.size() // ->4
s.add('wu') // ->{"1","er","san","si","wu"}
Map

它类似于对象,也是键值对的结合。“键”的范围不限于字符串,各种类型的(包含对象)都可以当做键

Map也实现了iterator接口,可以使用扩展运算符和for…of遍历。

Map的属性和方法

size 返回Map的元素个数
set 增加一个新元素,返回当前Map
get 返回键名对象的键值
has 检测Map中是否包含某个元素,返回boolean值
clear 清空集合,返回undefined

class类

ES6提供了更接近传统语言的写法,引入Class 概念。

基本上ES6的class可以看做是一个语法糖,其绝大多数ES5够可以做到。

新的class写法只是让对象原型的写法更加清晰,更像面向对象编程的语法

主要知识点

  • class声明类
  • constructor定义构造函数初始化
  • extends继承父类
  • super调用父级构造方法
  • static定义静态方法和属性(静态方法属于类,不属于实例化对象)
  • 父类方法可以重写
  • ES5写法
1
2
3
4
5
6
7
8
9
function Phone(brand,price){
this.brand = brand // brand:品牌
this.price = price
}
Phone.prototype.call = function(){ // 添加方法
console.log("打电话")
}
let Huawei = new Phone('华为',4999) // 实例化对象
Huawei.call()
  • ES6写法
1
2
3
4
5
6
7
8
9
10
11
class Phone{
constructor(brand,price){ // 构造方法,名字不能修改
this.brand = brand
this.price = price
}
call(){ // 方法必须使用该语法,不能使用ES5的对象完整形式
console.log('打电话')
}
}
let onePlus = new Phone("1+",4999)
onePlus.call()

数值扩展&对象方法扩展

数值扩展
  • Number.EPSION

Number.EPSION 是 JavaScript 表示的最小精度

EPSILON属性的值接近于2.220446049250313e-16

引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。我们知道浮点数计算是不精确的

1
2
3
4
5
6
0.1+0.2  // 0.30000000000000004
function equal(a, b) {
return Math.abs(a - b) < Number.EPSILON
}
console.log(equal(0.1 + 0.1, 0.2))
console.log(0.1 + 0.2 === 0.3)
  • 二进制、八进制、十进制、十六进制
1
2
3
4
let b = 0b1010 // 10
let o = 0o777 // 511
let d = 100 // 100
let x = 0xff // 255

下面这些,在Es5中可能是单独的方法,ES6中将其放到,对象下

举例:ES5中 isFinite(Infinity) ES6中 Number.isFinite(Infinity)

Number.isFinite 检测一个数值是否为有限数
Number.isNan 检测一个数是否为NaN
Number.parseInt 字符串转数组-整数Int
Number.parseFloat 字符串转数组-浮点数Float
Number.isInteger 判断一个数是否为整数
Math.trunc 将数字的小数部分抹掉
Math.sign 检测一个数,正数(返回1) 负数(0) 零(-1)
对象方法扩展
Object.is 判断两个值是否完全相等
Object.assign 对象的合并(重复的覆盖)
Object.setPrototypeOf 设置原型对象
Object.getPrototypeOf 获取原型对象

模块化

基本的暴露于导入

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

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

  • export:规定模块的对外接口
  • import:输入其他模块提供的功能
  • 三种暴露方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 分别暴露
export let school = 'string'
export function teach(){
cosole.log('我可以教你知识')
}
// 统一暴露
let school = 'string'
function teach(){
cosole.log('我可以教你知识')
}
export {school,teach}
// 默认暴露
export default {
school:'qinghua',
change: function(){
console.log('大学期间的学识,可以改变你的一生')
}
}
  • 导入方式
1
2
3
4
5
6
7
8
9
10
11
12
// 通用导入方式
import * as m1 from "./m1.js"
console.log(m1.school) // string
// 解构赋值形式
import {school,teach} from "./m1.js"
console.log(school)
import {school as xuexiao } from "./m2.js" // 导入的不同模块重名,可以使用呢as起别名
console.log(xuexiao)
import {default as m3} from './m3.js'
console.log(m3.school) // qinghua
// 简便形式 针对默认暴露
import m3 from './m3.js'
babel转化ES

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

编译打包为es5过程,局部安装用npx 全局安装不需要

  • 安装工具 babel-cli babel-preset-env browserify(webpack)
  • npx babel src/js -d dist/js | 原路径,编译后路径
  • 打包 npx browserify dist/app.js -o dist/bundle.js
  • 使用npm
1
2
3
import $ from 'jquery' // const $ = require('jquery')
$('body').css('background','pink')
// 后面正常编译打包就好

ES7新特性

Array.prototype.includes

Includes 方法用来检测数组中是否包含某个元素,返回Boolean,indexOf也可以实现类似功能

1
2
const mingzu = ['西游记','红楼梦','三国演义','水浒传']
console.log(mingzhu.includex('西游记')) // true

指数操作符 **

ES7中引入指数运算符 ** ,用来实现幂运算,功能与Math.pow结果相同

1
2
console.log(2**10)      // 1024
console.log(Math.pow(2,10)) // 1024

ES8新特性

async和await

async和await两种语法结合让异步代码像同步代码一样

  • async函数

async函数的返回值为promise对象

promise对象的结果又async函数执行的返回值决定

  • await表达式

await 必须写在async函数中

await右侧的表达式一般为promise对象

await返回的是promise成功的值

await的promise失败了,就会抛出异常,需要通过 tru ... catch 捕获异常

对象方法 扩展

Object.values 返回一个给定对象的所有可枚举属性值的数组
Object.entries 返回一个给定对象自身可遍历属性 [key,value] 的数组
Object.getOwnPropertyDescriptors 返回指定对象所有自身属性的描述对象
1
2
3
4
5
6
7
8
9
10
const school = { // 声明对象
name:'qinghua',
cities:['北京','上海','广州','深圳'],
xueke:['前端','python','nodejs','php']
}
console.log(Object.keys(school)) // 获取所有的键 ["name", "cities", "xueke"]
console.log(Object.values(school)) // 获取有的值 ["qinghua", Array(4), Array(4)]
console.log(Object.entries(school)) // [[key1,value1],[key2,value2]...],可用于生产Map
console.log(new Map(Object.entries(school)))
console.log(new Map(Object.entries(school)).get('name')) // 'qinghua'

image-20200717213939005

1
2
3
4
5
6
7
console.log(Object.getOwnPropertyDescriptors(school)) // 返回对象属性的 描述对象   见下图
const obj = Object.create(null,{ // 第一个参数:原型对象,第二个参数:描述对象
value:'yishe', // getOwnPropertyDescriptors返回的就是描述对象
writable:true, // 是否可写,(writable cofigurable enumerable)属性特性
cofigurable:true, // 是否可以删除,属性特性克隆对象时也许会用到
enumerable:true // 是否可以枚举
})

ES9新特性

Rest参数、spread扩展运算符

ES6中已经引入,在ES9中为对象提供了像数组一样的rest参数和扩展运算符

  • rest参数在对象中的应用
1
2
3
4
5
6
7
8
9
10
11
function connect({host,port,...user}){
console.log(host)
console.log(port)
console.log(user) // user是包含username和password的对象
}
conect({
host:'127.0.0.1',
port:3306,
username:'root',
password:'root'
})
  • 扩展运算符在对象中的应用

可以将对象展开成key:value,的形式;与展开数组类似

image-20200717222718056

正则扩展

正则基础知识-菜鸟教程 自己总结的-xmind-蓝奏云-下载路径

正则扩展-命名捕获分组
1
2
3
4
5
6
// 传统方式,没用正则扩展
let str = '<a href="http://blog.mdashen.com">yishenBlog</a>'
const reg = /<a href="(.*)">(.*)<\/a>/
console.log(reg.exec(str)) //正则匹配href属性的值,和标签内容内容
// 正则扩展
const reg2 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/ // 类似于给匹配到的内容起一个别名

image-20200718100716330

正则扩展-反向断言

正则匹配时,有多个匹配到的内容;可以根据目标前面或后面,来对目标进行唯一性识别

1
2
3
let str = 'Js34342你知道吗555啦啦啦'
const reg = /\d+(?=啦)/ // 匹配后面是'啦'的数值 正向断言
const reg1 = /(?<=吗)\d+/ // 匹配前面是'吗'的数值 反向断言
正则扩展-dotAll模式

dot . 元字符 除换行符以外的任意单个字符

const reg = /正则内容/s ,末尾增加s,使’.’可以匹配换行符

ES10新特性

对象扩展方法

Object.fromEntries

用来创建一个对象,参数是一个二维数组或者Map对象( 将二维数组或者Map对象转化为对象 )

Object.entries 为逆运算

字符串扩展方法

trimStart、trimEnd

ES5中有 trim方法用来清除字符串两边的空白字符

trimStart:清除左侧空白字符,保留右侧空白字符

trimEnd:清除右侧空白字符,保留左侧空白字符

数组方法扩展

flat、flatMap
  • flap

flap:拍打、平

将多维数组转化为低维数组 arr.flat(argus) 参数为深度,3维转1维深度为2

  • flapMap

如果arr.map()返回的是一个二维数组,可以使用flapMap代替map,返回一维数组

image-20200718120616747

Symbol方法扩展

Symbol.prototype.description

获取Symbol的字符串描述

1
2
let s = Symbol('yishen')
s.description // -> yishen

ES11新特性

私有属性

只能在类的内部对其进行修改和访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 Personn('小红',18,'45kg')
console.log(girl) // 正常访问
console.log(girl.#age) // 在类的外部无法访问私有属性

Promise.allSettled

接收一个promise数组,返回promise对象(永远是成功的状态)

返回的值是每一个promise的状态和结果

参考链接-allSettled 扩展阅读-Promise 中的三兄弟 .all(), .race(), .allSettled()

image-20200718122325135

  • Promise.all([p1,p2])

全部成功,才返回成功,有一个失败就返回失败
Promise.all 和 Promise.allSettled常用于批量异步任务

字符串扩展

String.prototype.matchAll

用来得到正则批量匹配得到的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let str = `
<ul>
<li>
<a>肖申克的救赎</a>
<p>上映日期:1994-0910</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-0716</p>
</li>
</ul>
`
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg // [s](#正则扩展-dotAll模式)
const result = str.matchAll(reg)
// for (let v of result) { // 与下面...一个功能
// console.log(v)
// }
console.log([...result])

可选链操作符?

按照操作符之前的属性是否有效,链式读取对象的属性或者使整个对象链返回 undefined

1
2
3
4
5
6
7
8
9
10
11
12
function main(config){
const dbHost = config && config.db && config.db.host // config &&判断config是否存在
console.log(dbHost) // 当config存在,才能读取config.db
} // 不先判断,当config不存在,直接config.db会报错
main({
db:{
host:'192.168.0.2',
username:'root'
}
})
// 可选链操作符?.
const dbHost = config?.db?.host // 可以起到上述判断的作用

动态import

当使用到需要导入的模块时,才导入。提升加载效率

1
2
3
4
5
6
const btn = document.getElementById('btn')
btn.onclick = function(){
import('./hello.js').then(module=>{ // import返回promise对象,module就是导入的对象
module.hello() // hello()hello.js中一个普通方法
})
}

BigInt

用于大数值运算

1
2
3
4
let n = 521n // 大整型
console.log(n,typeof(n)) // 521n "bigint"
let n1 = 521
BigInt(n1) // 普通整型转大整型 -> 521n
1
2
3
4
5
6
7
8
let max = Number.MAX_SAFE_INTEGER // 9007199254740991
console.log(max)
console.log(max+1) // 正常
console.log(max+2) // 不正常,在向后加,有的正常有的不正常

console.log(BigInt(max))
console.log(BigInt(max)+BigInt(1)) // 正常,BigInt 不能直接与Int运算,要先转成BigInt
console.log(BigInt(max)+BigInt(2)) // 正常

globalThis

始终指向全局对象,无论执行环境是什么(浏览器、nodejs)
浏览器下指:Window

nodejs下指:global

image-20200718175918068