Javascript[ECMAScript] 新特性—1

背景

JS1.1(1997)

第一版基于Netscape Navigator 3.0中实现的JAVASCRIPT 1.1

JS1.2(1999)

基于Netscape Navigator 4.0中实现的JavaScript 1.2。添加了正则表达式、更好的字符串处理、新的控制语句、Try/Catch异常处理、更严格的错误定义、数字输出格式以及其他增强功能

ES5(2015)

1.严格模式

use strict

2.Object

  • getPrototypeOf,返回一个对象的原型
  • getOwnPropertyDescriptor,返回某个对象自有属性的属性描述符
  • getOwnPropertyNames,返回一个数组,包括对象所有自由属性名称集合(包括不可枚举的属性)
  • hasOwnProperty,给定属性存在于对象实例中,返回 true
  • isPrototypeOf,在原型链中出现过的原型,返回 true
  • create,创建一个拥有指定原型和若干指定属性的对象
  • defineProperty,为对象定义一个新属性,或者修改已有的属性,并对属性重新设置 getter 和 setter,这里可以被用作数据绑定的对象劫持用途
  • defineProperties,在一个对象上添加或修改一个或者多个自有属性,与 defineProperty 类似
  • seal,锁定对象,阻止修改现有属性的特性,并阻止添加新属性,但是可以修改已有属性的值
  • freeze,冻结对象,阻止对对象的一切操作和更改,冻结对象将变成只读
  • preventExtensions,让一个对象变得不可以扩展,也就是不能再添加新的属性
  • isSealed,判断对象是否被锁定
  • isFrozen,判断对象是否被冻结
  • isExtensible,判断对象是否可以被扩展
  • keys,返回一个由给定对象的所有可以枚举自身属性的属性名组成的数组

3.Array

  • Array.isArray,确定某个值到底是不是数组,不管它在哪个全局执行环境中创建
  • push,接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度
  • pop,在数组尾部移除最后一项,减少数组的 length 值,然后返回移除的项
  • shift,移除数组中的第一项并返回该项,同时将数组长度减 1
  • unshift,在数组前端添加任意个项,并返回新数组的长度
  • reverse,反转数组项的顺序,返回排序后的数组
  • sort,默认情况下,按升序排序数组项,返回排序后的数组
  • concat,创建当前数组的一个副本,将接收到的参数添加到这个副本的末尾,返回新构建的数组
  • join,用指定的字符拼接数组,返回拼接好的字符串
  • slice,基于当前数组中的一个或多个创建一个新数组,不影响原始数组
  • splice,根据传入参数不同,可以删除、插入、替换数组元素,返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回空数组
  • indexOf,返回根据给定元素找到的第一个索引值,如果不存在则返回 -1
  • lastIndexOf,返回指定元素在数组中的最后一个索引值,如果不存在则返回 -1
  • every ,对数组中的每一项运行给定函数 ,如果该函数对每一项都返回 true,则返回 true
  • filter,对数组中的每一项运行给定函数 ,返回该函数会返回 true 的项组成的数组
  • forEach,对数组中的每一项运行给定函数,没有返回值
  • map,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
  • some,对数组中的每一项运行给定函数,如果���数对任一项返回 true,则返回 truereduce,接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终缩减为一个值
  • reduceRight,接收一个函数作为累加器,数组中的每个值(从右到左)开始缩减,最终缩减为一个值

4.String

  • charAt,访问字符串中特定字符,返回给定位置的字符
  • charCodeAt,访问字符串中特定字符,返回给定位置的字符的字符编码
  • concat,将一个或多个字符串拼接起来,返回拼接得到的新字符串
  • match,查找匹配的字符串,返回一个数组
  • search,查找匹配的字符串,返回匹配项的索引,没有找到,返回 -1
  • replace,替换字符串
  • split,基于指定的分隔符将一个字符串分割成多个字符串,将结果放在一个数组中,并返回
  • trim,创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果
  • localeCompare,比较两个字符串
  • slice,返回被操作字符串的一个子字符串
  • substr,返回被操作字符串的一个子字符串
  • substring,返回被操作字符串的一个子字符串

注意:slice、substr、substring 都接受一个或两个参数,第一个参数指定字符串的开始位置,第二个参数表示子字符串到哪里结束,slice 和 substring 的第二个参数指定的是子字符串的最后一个字符后面的位置,substr 第二个参数指定的是返回的字符个数,如果没有传递第二个参数,则将字符串的末尾作为结束位置。

5.Function

  • arguments.callee,该属性是一个指针,指向拥有这个 arguments 对象的函数
  • arguments.caller,该属性保存着调用当前函数的函数的引用
  • apply,在特定的作用域中调用函数,第一个参数是在其中运行函数的作用域,第二个是参数数组
  • call,在特定的作用域中调用函数,第一个参数是在其中运行函数的作用域,其余参数直接传递给函数
  • bind,创建一个函数的实例,其 this 值会被绑定到传给 bind 函数的值

6.JSON

  • JSON.parse,解析字符串为 JSON 对象
  • JSON.stringify,解析 JSON 对象为字符串
  • JSON.valueOf,获取某个JSON 对象中的值
  • JSON.toString,被调用时,会调用 Object 原型上的 toString 方法,会获的 JSON 对象的值并转为字符串,如果没有具体的值,则返回原型数组
  • JSON.toLocaleString,也是Object 原型上的方法,经常会返回与 toString 相同内容,但是对于 Date 对象,则会返回格式化的时间字符串

7.其他

  • Date.now,返回当前时间戳
  • Date.toJSON,将 Date 对象转换为字符串,格式为 JSON 日期
  • Math.min,确定一组数值中的最小值
  • Math.max,确定一组数值中的最大值
  • Math.random,返回大于 0 小于 1 的一个随机数
  • Number.prototype.toFixed,按照指定的小数位返回数值的字符串表示

ES6(2015)

1. 类(class)

class Man {
  constructor(name) {
    this.name = '你好世界';
  }
  console() {
    console.log(this.name);
  }
}
const man = new Man('你好世界');
man.console(); // 你好世界

2. 模块化(ES Module)

// 模块 A 导出一个方法
export const sub = (a, b) => a + b;
// 模块 B 导入使用
import { sub } from './A';
console.log(sub(1, 2)); // 3

3. 箭头(Arrow)函数

const func = (a, b) => a + b;
func(1, 2); // 3

4. 函数参数默认值

function foo(age = 25,){ // ...}

5. 模板字符串

const name = '你好世界';
const str = `Your name is ${name}`;

6. 解构赋值

let a = 1, b= 2;
[a, b] = [b, a]; // a 2  b 1

7. 延展操作符

let a = [...'hello world']; // ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]

8. 对象属性简写

const name='你好世界',
const obj = { name };

9. Promise

Promise 代表一个异步操作的执行返回状态,这个执行返回状态在 Promise 对象创建时是未知的,它允许为异步操作的成功或失败指定处理方法。

9.1 Promise 的状态有三种:
  • Fulfilled,表示 Promise 执行成功
  • Rejected,表示 Promise 执行失败
  • Pending,表示 Promise 正在执行中
9.2 Promise 对象有两个特点:
  • 对象的状态不受外界影响
  • 一旦状态改变就不会再变,任何时候都可以得到这个结果
9.3 缺点:
  • 无法取消 Promise,一旦新建它就会立即执行,无法中途取消
  • 如果不设置回调函数,Promise 内部抛出的错误不会反应到外部
  • 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚开始还是即将完成)
9.4 基本用法:
var promise = new Promise(function(resolve, reject) {
    // ... some code

    if ( /*异步操作成功*/ ) {
        resolve(value)
    } else {
        reject(error)
    }
})

promise.then(function(value) {
    // success
}, function(error) {
    // failure
})

9.5 Promise 实例方法:
  • Promise.prototype.then(),为 Promise 实例添加状态改变时的回调函数,返回一个新的 Promise 实例
  • Promise.prototype.catch(),用于指定发生错误时的回调函数,返回一个新的 Promise 实例
  • Promise.prototype.done(),总是处于回调链的尾端,保证捕捉到任何可能出现的错误
  • Promise.prototype.finally(),用于指定不管 Promise 对象最后状态如何都会执行的操作。

finally 与 done 的最大区别在于:finally 接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。

9.6 Promise 对象方法:
  • Promise.all(),将多个 Promise 实例包装成一个新的 Promise 实例。

var p = Promise.all([p1, p2, p3])

p 的状态由 p1,p2,p3 决定:

第一,只有 p1,p2,p3 的状态都编程 Fulfilled,p 的状态才会变成 Fulfilled,此时p1,p2,p3 的返回值组成一个数组,传递给 p 的回调函数。

第二,只要 p1,p2,p3 中有一个被 Rejected,p 的状态就变成 Rejected,此时第一个被 Rejected 的实例的返回值会传递给 p 的回调函数

  • Promise.race(),将多个 Promise 实例包装成一个新的 Promise 实例。
 

var p = Promise.race([p1, p2, p3])

只要 p1,p2,p3 中有一个实例率先改变状态,p 的状态就跟着改变,那个率先改变的 Promise 实例的返回值就传递给 p 的回调函数。

  • Promise.resolve(),将现有对象转为 Promise 对象,状态为 Resolved
  • Promise.reject(),将现有对象转为 Promise 对象,状态为 Rejected
Promise.resolve().then(() => { console.log(2); });
console.log(1);
// 先打印 1 ,再打印 2

10. let和const

let name = '你好世界';
const arr = [];

11. 数组的新特性

ES6 为数组内置对象添加了较多的新特性,主要包括 ... 复制数组和新增的数组 API。

const arr = [1, 2, 3]
const newArr = [...arr]  //[1, 2, 3]

注意:这里 ... 进行的数组复制是浅拷贝

ES6 数组的新增方法:

  • Array.from,用于将类数组对象(包括 [array-like object] 和可遍历对象)转化为真正的数组
  • Array.of,可以将传入的一组参数值转换为数组
  • Array.prototype.copyWithin,可以在当前数组内部将指定位置的数组项复制到其他位置,然后返回当前数组,使用 copyWithin 方法会修改当前数组
  • Array.prototype.fill,使用给定值,填充一个数组,会改变原来的数组
  • Array.prototype.find,用于找出第一个符合条件的数组元素,有点类似于 filter
  • Array.prototype.findIndex,用来返回某个特定数组元素在数组中的位置
  • Array.prototype.entries,对数组中键值对进行遍历
  • Array.prototype.keys,对数组键名进行遍历
  • Array.prototype.values,对数组键值进行遍历
  • for...of 循环进行遍历
  • Array.prototype[Symbol.iterator],用来获取遍历数组对象的迭代器

11. 函数参数

ES6 对函数参数进行了新的设计,主要添加了默认参数、不定参数和扩展参数:

// 默认参数
function sayHi(name = 'zhangsan') {
    console.log(`Hello ${name}`)
}
sayHi() // Hello zhangsan


// 不定参数
function sayHi(...name) {
    console.log(name.reduce((a, b) => `Hello ${a} ${b}`))
}
sayHi('zhangsan', 'lisi') 


// 扩展参数
let name = ['zhangsan', 'lisi']
function sayHi(name1, name2) {
    console.log(`Hello ${name1} ${name2}`)
}
sayHi(...name) 

不定参数和扩展参数可以认为恰好是相反的两个模式,不定参数是使用数组来表示多个参数,扩展参数则是将多个参数映射到一个数组。

需要注意:不定参数的 ... 和数组复制的 ... 是有区别的,不定参数可以使用函数的形参来表示所有的参数组成的列表。以前的 arguments 变量也有类似的作用,但是 arguments 不是真正的数组,除了存放参数的列表外,arguments 还有 length 属性,严格来说 arguments 是一个类数组对象,而不定参数则是一个完全的数组,这也是不定参数相对于 arguments 的优势,更加方便我们使用,所以建议使用不定参数来代替 arguments。

12. 集合类型 Map + Set + WeakMap + WeakSet

12.1 Set

Set 本身是一个构造函数 ,用来生成 Set 数据结构,Set 类似于数组(但它不是数组),Set 的成员的值都是唯一的,没有重复的值,也常用它来去重(不可以传递对象)。像 Set 加入值的时候,不会发生类型转换,所以 5 和 “5” 是两个不同的值。

const arr = new Set([1, 2, 3, 4, 5, 5, 5, 5])

console.log(arr)  //[1, 2, 3, 4, 5]
console.log(arr.size)  //5 

操作方法:

  • add(value),添加某个值,返回 Set 结构本身
  • delete value,删除某个值,返回一个布尔值,表示删除是否成功
  • has(value),返回一个布尔值,表示该值是否为 Set 成员
  • clear(),清除所有成员,没有返回值

遍历方法:

  • keys(),返回键名的遍历器
  • values(),返回键值的遍历器
  • entries(),返回键值对的遍历器
  • forEach(),使用回调函数遍历每个成员
12.2 WeakSet

WeakSet 结构与 Set 类似,也是不重复的值的集合,但是,它与 Set 有两个区别:

第一,WeakSet 的成员只能是对象,而不能是其他类型的值。

第二,WeakSet 中的对象都是弱引用,即垃圾回收机制 不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不在引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象是否还存在于 WeakSet 中。因此 ES6 规定 WeakSet 不可遍历。

12.3 Map

传统的 JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是只能用字符串当做键,这给它的使用带来了很大的限制,而 ES6 提供了 Map 数据结构,它类似于对象,也是键值对的集合,但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当做键。也就是说,Object 结构提供了“字符串-值”的对应,Map 结构提供了“值-值”的对应,是一种更完善的 Hash 结构实现。Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。

操作方法:

  • set(key, value),设置 key 所对应的键值,返回整个 Map 结构 ,如果 key 已经有值,则键值会被更新,否则就生成该键
  • get(key),读取 key 对应的键值,如果在好不到 key,则返回 undefined
  • has(key),返回一个 布尔值,表示某个键是否在 Map 数据结构中
  • delete(key),删除某个键,返回 true,如果删除失败,则返回 false
  • clear(),清除所有成员,没有返回值

遍历方法:

  • keys(),返回键名的遍历器
  • values(),返回键值的遍历器
  • entries(),返回所有成员的遍历器
  • forEach(),遍历 Map 的所有成员
12.4 WeakMap

WeakMap 结构与 Map 结构类似,也用于生成键值对的集合,但 WeakMap 与 Map 有两个个区别:

第一,WeakMap 只接受对象作为键名(null 除外),不接受其他类型的值作为键名。

第二,WeakMap 的键名所指向的对象不计入垃圾回收机制。它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内,因此,只要所引用的对象的其他引用被清除了,垃圾回收机制就会释放该对象所占用的内存。也就是说, 一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。基本上,如果要想对象中添加数据又不想干扰垃圾回收机制,便可以使用 WeakMap。一个典型的应用场景是,在网页的 DOM 元素上添加数据时就可以使用 WeakMap 结构,当该 DOM 元素被清除,其对应的 WeakMap 记录就会自动被移除。

注意:WeakMap 的专用场景就是它的键所对应的对象可能会在将来消失,WeakMap 结构有助于防止内存泄露。但是,WeakMap 弱引用的只是键名而不是键值,键值依然是正常引用的。

13. Symbol 类型

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值,它是 JavaScript 语言的第 7 种数据类型,前 6 种分别是:Undefined、Null、Boolean、String、Number 和 Object。

Symbol 值通过 Symbol 函数生成,一般作为属性键值,并且能避免对象属性键的命名冲突。也就是说,对象的属性名现在可以有两种类型:一种是原来就有的字符串,另一种就是新增的 Symbol 类型。只要属性名属于 Symbol 类型,就是独一无二的,可以保证不会与其他属性名产生冲突。

let s = Symbol('foo') typeof s //"symbol"

注意:

Symbol 函数前不能使用 new 命令,否则会报错,这是因为生产的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

Symbol 函数的参数只表示对当前 Symbol 值的描述,因此相同参数的 Symbol 函数的返回值是不相等的。

Symbol 值作为对象属性名时不能使用点运算符:

let s = Symbol()

let obj = {
    [s]: function() {
        console.log('Hello')
    }
}

obj[s]()  // 'Hello'

Symbol 做为属性名,该属性不会出现在 for...in,for...of 循环中,也不会被 Object.keys()、Object.getOwnpropertyNames() 返回,但它也不是私有属性,Object.getOwnPropertySymbols() 可以获取指定对象的所有 Symbol 属性名。 Object.getOwnPropertySymbols() 返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

Proxy

Proxy 用于修改某些操作的默认行为,可以用来拦截某个对象的属性访问方法,然后重载对象的 “ . ” 运算符。

Proxy 可以理解成在目标对象前架设一个“拦截”层,外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。

let object = new Proxy({}, {
    get: function(target, key, receiver) {
        console.log(`getting ${key}`)
        return Reflect.get(target, key, receiver)
    },
    set: function(target, key, value, receiver) {
        console.log(`setting ${key}`)
        return Reflect.set(target, key, value, receiver)
    }
})

对比 Object.defineProperty 方法:

let object = {},
    value

Object.defineProperty(object, 'value', {
    get: function() {
        console.log('getting value')
        return value
    },
    set: function(newValue) {
        value = newValue
        console.log('setting: ' + newValue)
    },
    enumerable: true,
    configurable: true
})

Reflect

Reflect 对象的设计目的有以下几个:

第一,将 Object 对象的一些明显属于语言内部的方法(如 Object.defineProperty)放到 Reflect 对象上,现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来新的方法只在 Reflect 对象上部署。也就是说,从 Reflect 对象上可以获得语言内部的方法。

第二,修改某些 Object 方法的返回结果,让其变得更加合理。

第三,让 Object 操作都编程函数行为,某些 Object 操作是命令式,比如 name in obj 和 delete obj [name],而 Reflect.has(obj, name) 和 Reflect.deleteProperty(obj, name) 让它们变成了函数行为。

第四,Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法,这就是 Proxy 对象可以方便的调用对应的 Reflect 方法来完成默认行为,作为修改行为的基础。也就是说,无论 Proxy 怎么修改默认行为,我们总可以在 Reflect 上获取到默认行为。

Iterator

Iterator即迭代器,它是一种接口,为各种不同的数据结构提供了统一的访问机制,换句话说,只要有任何数据结构部署了迭代接口,就可以使用统一的方式的来遍历它。

实现可迭代接口的数据结构,一般都自身实现或继承了以Symbol.iterator属性的,就属于可迭代对象。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。

一个包含next()方法的对象,才可以称为一个迭代对象。next()对象的会有返回一个对象,对象中包含两个值,如下所示:

  • value:迭代器返回的任何JavaScript值。donetrue时可省略。
  • done:一个布尔值,为false时表示迭代未停止,为true时立即停止迭代器,且可以省略value的值。

JavaScript原生提供的迭代器接口如下图所示:

image.png

Generator

Generator是ES2015中提供的一种异步编程解决方案,定义Generator函数在function关键字和函数名中间使用*星号,函数内部使用yield关键字定义不同的状态。

示例代码如下:

function* testGenerator() {
  // yield定义一个状态
  yield '一碗周'
  yield 'es新特性'
  return 'generator' // 终结Generator,后面即使有yield关键字也无效
}
const g = testGenerator() // 返回 Generator 对象,通过next()方法移动状态

g.next()
/* { value: '一碗周', done: false } */

g.next()
/* { value: 'es新特性', done: false } */

g.next()
/* { value: 'generator', done: true } */

ES7(2016)

1. 幂指数操作符

增加了幂指数操作符来进行幂指数运算:

console.log(2 ** 3) // 8

x ** y 产生的结果等同于 Math.pow(x, y)

2. Array.prototype.includes

这个数组方法主要用来判断数组中是否包含某个元素:

let num = [1, 2, 3, 4, 5]

console.log(num.includes(1))  // true

ES8(2017)

1. 异步函数 async/await

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

function timeout(ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    })
}

async function asyncPrint(value, ms) {
    await timeout(ms)
    console.log(value)
}

asyncPrint('Hello', 300)

上诉代码指定 300ms 后输出 Hello。

async 函数返回一个 Promise 对象,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数:

async function f() {
    return 'Hello'
}

f().then(v => console.log(v))  // 'Hello'

tion f() { return 'Hello' } f().then(v => console.log(v)) // 'Hello'

async 函数内部抛出错误会导致返回的 Promise 对象变成 rejected 状态,抛出的错误对象会被 catch 方法回调函数接受到:

async function f() {
    throw new Error('出错了')
}

f().then(
    v => console.log(v),
    e => console.log(e)
)   // ‘Error: 出错了’

正常情况下,await 命令后面是一个 Promise 对象,如果不是,会被转为一个立即 resolve 的 Promise 对象。

await 命令后面的 Promise 对象如果变成 rejected 状态,则 reject 的参数会被 catch 方法的回调函数接收到。

只要一个 await 语句后面的 Promise 变成 rejected,那么整个 async 函数都会被中断执行。

注意:

  • await 命令后面的 Promise 对象的运行结果可能是 rejected,最好把 await 命令放在 try...catch 中。
  • 多个 await 命令后面的异步操作如果不存在继发关系,最好让它们同时触发。
  • await 命令只能用在 async 函数中,如果用在普通函数中就会报错。

2. Object.values()

Object.values({a: 1, b: 2, c: 3}); // [1, 2, 3]

3. Object.entries()

Object.entries({a: 1, b: 2, c: 3}); // [["a", 1], ["b", 2], ["c", 3]]

4. Object.getOwnPropertyDescriptors()

5. String padding

// padStart
'hello'.padStart(10); // "     hello"
// padEnd
'hello'.padEnd(10) "hello     "

6. 函数参数列表结尾允许逗号

7. Object.getOwnPropertyDescriptors()

获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

8. SharedArrayBuffer对象

SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,

/**
 * 
 * @param {*} length 所创建的数组缓冲区的大小,以字节(byte)为单位。  
 * @returns {SharedArrayBuffer} 一个大小指定的新 SharedArrayBuffer 对象。其内容被初始化为 0。
 */
new SharedArrayBuffer(10)

9. Atomics对象

Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。

ES9(2018)

1. 异步迭代

await可以和for...of循环一起使用,以串行的方式运行异步操作

async function process(array) {
  for await (let i of array) {
    // doSomething(i);
  }
}

2. Promise.finally()

Promise.resolve().then().catch(e => e).finally();

3. Rest/Spread 属性

const values = [1, 2, 3, 5, 6]; console.log( Math.max(...values) ); // 6

4. 正则表达式命名捕获组

const reg = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
const match = reg.exec('2021-02-23');
 

image.png

5. 正则表达式反向断言

(?=p)、(?<=p) p 前面(位置)、p 后面(位置)

(?!p)、(?<!p>) 除了 p 前面(位置)、除了 p 后面(位置)

(?<=w)

image.png

(?<!w)

image.png

6. 正则表达式dotAll模式

正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现

 

/hello.world/.test('hello\nworld'); // false

image.png

ES10(2019)

1. Array.flat()和Array.flatMap()

flat()

[1, 2, [3, 4]].flat(Infinity); // [1, 2, 3, 4]

flatMap()

[1, 2, 3, 4].flatMap(a => [a**2]); // [1, 4, 9, 16]

2. String.trimStart()和String.trimEnd()

去除字符串首尾空白字符

3. String.prototype.matchAll

matchAll()为所有匹配的匹配对象返回一个迭代器

const raw_arr = 'test1  test2  test3'.matchAll((/t(e)(st(\d?))/g));
const arr = [...raw_arr]

4. Symbol.prototype.description

只读属性,回 Symbol 对象的可选描述的字符串。

Symbol('description').description; // 'description'

5. Object.fromEntries()

返回一个给定对象自身可枚举属性的键值对数组

// 通过 Object.fromEntries, 可以将 Map 转化为 Object:
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
console.log(Object.fromEntries(map)); // { foo: "bar", baz: 42 }

6. 可选 Catch

try { // 一段可能抛出异常的代码 throw new Error('Something went wrong'); } catch { // 没有指定参数,捕获到的异常对象不会被赋给任何变量 console.log('An error occurred but no information is captured.'); }

@:冉冉同学已授权
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/793324.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt/C++项目积累: 2.主机监控器 - 2.2 历史功能实现

修订历史&#xff1a; 20240711&#xff1a;初始表设计&#xff0c;采用sqlite 正文&#xff1a; 关于历史数据存储&#xff0c;考虑的是用数据库来完成&#xff0c;目前考虑使用Sqlite和mysql&#xff0c;先用sqlite来实现&#xff0c;设计表过程如下&#xff1a; 机器总览…

SpringBoot 3.3 【一】手把手讲解-使用Eclipse创建第一个SpringBoot应用程序

简单动作&#xff0c;深刻联结。在这技术海洋&#xff0c;我备好舟&#xff0c;等你扬帆。启航吧&#xff01; &#x1f31f;点击【关注】&#xff0c;解锁定期的技术惊喜&#xff0c;让灵感与知识的源泉不断涌动。 &#x1f44d;一个【点赞】&#xff0c;如同心照不宣的默契&a…

FL Studio21.9.821最新中文版来啦!附带永久免费下载地址

【音乐制作新宠&#xff0c;FL Studio21中文版来啦&#xff01;&#x1f389;】 嘿&#xff0c;音乐爱好者们&#x1f3a7;&#xff0c;今天要给大家种草一个超酷炫的宝贝儿——FL Studio21中文版&#xff01;这货简直就是音乐制作界的小可爱加实力派&#xff0c;让我彻底沦陷了…

Dify中的RAG和知识库

一.RAG 基本架构 当用户提问 “美国总统是谁&#xff1f;” 时&#xff0c;系统并不是将问题直接交给大模型来回答&#xff0c;而是先将用户问题在知识库中进行向量搜索&#xff0c;通过语义相似度匹配的方式查询到相关的内容&#xff08;拜登是美国现任第46届总统…&#xff0…

2024年7月2日~2024年7月8日周报

目录 一、前言 二、完成情况 2.1 吴恩达机器学习系列课程 2.1.1 分类问题 2.1.2 假说表示 2.1.3 判定边界 2.2 学习数学表达式 2.3 论文写作情况 2.3.1 题目选取 2.3.2 摘要 2.3.3 关键词 2.3.4 引言部分 2.3.4 文献综述部分 三、下周计划 3.1 存在的问题 3.2 …

Java高级重点知识点-24-函数式接口

文章目录 函数式接口函数式编程常用函数式接口 函数式接口 有且仅有一个抽象方法的接口。 格式&#xff1a; 修饰符 interface 接口名称 {public abstract 返回值类型 方法名称(可选参数信息);// 其他非抽象方法内容 }public interface MyFunctionalInterface {void myMethod…

企事业网站需要做软件测试吗?包括哪些测试内容和好处?

在这个数字化时代&#xff0c;企事业网站已经成为宣传和交流的重要平台&#xff0c;它的稳定性、安全性和用户体验对于企业形象和业务发展至关重要。因此&#xff0c;为了确保企事业网站的良好运行&#xff0c;对其进行软件测试是至关重要的。那么网站测试具体有哪些好处?又包…

分享一款嵌入式开源LED指示灯控制代码框架cotLed

一、工程简介 cotLed是一款轻量级的LED控制软件框架&#xff0c;可以十分方便地控制及自定义LED的各种状态&#xff0c;移植方便&#xff0c;无需修改&#xff0c;只需要在初始化时实现单片机硬件GPIO初始化&#xff0c;同时为框架接口提供GPIO写函数即可。 框架代码工程地址&a…

【电子通识】无源元件与有源元件的定义和区别是什么?

当提到构成电路的电子器件时,许多人可能会想到晶体管、电容器、电感器和电阻器等器件。一般情况下,我们使用的电子器件分为两大类,即“有源元件”和“无源元件”。 有源元件是主动影响(如放大、整流、转换等)所供给电能的元件。 无源元件是对所供给的电能执行被动…

Linux编程第三篇:Linux简介,开源软件简介(Linux是否安全?参考TESEC指标)

业精于勤荒于嬉&#xff0c;行成于思毁于随。 今天这篇算是Linux的正式学习&#xff0c;废话不多说&#xff0c;我们开始吧 第三篇 一、UNIX与Linux发展史1.1、UNIX发展历史和发行版本1.2、UNIX主要发行版本1.3、Linux发展历史1.4、Linux内核版本1.5、Linux主要发行版本 二、开…

土木转行嵌入式,拿到一家初创公司的嵌入式研发offer,值得去吗

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;不论从未来行业的发展前景…

Linux 初识

目录 ​编辑 1.Linux发展史 1.1UNIX发展历史 1.2Linux发展历史 2.Linux的开源属性 2.1 开源软件的定义 2.2 Linux的开源许可证 2.3 开源社区与协作 3.Linux的企业应用现状 3.1 服务器 3.1.1 Web服务器 3.1.2 数据库服务器 3.1.3 文件服务器 3.1.4 电子邮件服务器 …

基于Android平台开发,备忘录记事本

相关视频教程在某站上面(&#x1f50d;浩宇软件开发) 1. 项目功能思维导图 2. 项目涉及到的技术点 使用CountDownTimer实现开屏页倒计时使用SQLite数据库存储数据使用BottomNavigationView实现底部导航栏使用ActivityFragment实现底部导航栏页面切换使用RecyclerViewadapter实…

uni-app/vue项目如何封装全局消息提示组件

效果图&#xff1a; 第一步&#xff1a;封装组件和方法&#xff0c;采用插件式注册&#xff01; 在项目目录下新建components文件夹&#xff0c;里面放两个文件&#xff0c;分别是index.vue和index.js. index.vue&#xff1a; <template><div class"toast&quo…

为什么广告需要教育视频

教育视频作为一种广告工具越来越受欢迎&#xff0c;因为它们能够有效地传达信息并吸引观众的注意力。以下是需要此类视频的几个关键原因&#xff1a; 提高参与度 互动性&#xff1a;教育视频吸引注意力&#xff0c;让观众长时间参与&#xff0c;并让他们参与学习过程。产品演…

具有 0.5V 超低输入电压的 3A 升压转换器TPS61021

1 特性 输入电压范围&#xff1a;0.5V 至 4.4V 启动时的最小输入电压为 0.9V 可设置的输出电压范围&#xff1a;1.8V 到 4.0V 效率高达 91%&#xff08;VIN 2.4V、VOUT 3.3V 且 IOUT 1.5A 时&#xff09; 2.0MHz 开关频率 IOUT > 1.5A&#xff0c;VOUT 3.3V&#xff08;V…

【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

使用Docker制作python项目镜像

各docker桌面版本集合&#xff1a;如果提示新版本系统不支持&#xff0c;可下载旧版本 我也分享在下面。 链接: https://pan.baidu.com/s/1HvaO2wOIE3pNE0bM7Qm3sA?pwdg7ky 提取码: g7ky –来自百度网盘超级会员v2的分享 来源参考&#xff1a;https://zhuanlan.zhihu.com/p/65…

C++|智能指针

目录 引入 一、智能指针的使用及原理 1.1RAII 1.2智能指针原理 1.3智能指针发展 1.3.1std::auto_ptr 1.3.2std::unique_ptr 1.3.3std::shared_ptr 二、循环引用问题及解决方法 2.1循环引用 2.2解决方法 三、删除器 四、C11和boost中智能指针的关系 引入 回顾上…

休息时间c++

题目描述 小杨计划在某个时刻开始学习&#xff0c;并决定在学习k秒后开始休息。 小杨想知道自己开始休息的时刻是多少。 输入 前三行每行包含一个整数&#xff0c;分别表示小杨开始学习时刻的时h、分m、秒s(h&#xff0c;m&#xff0c;s的值符合1≤h≤12,0≤m≤59,0≤s≤59)…