ES6+新特性

ES6+新特性

ES6(ES2015)

1.let const

let表示声明变量,const声明常量。

let不存在变量提升,不影响作用域链.

常量定义了就不能修改。对象除外,因为对象指向的地址没变,

const在声明时必须赋值。两者都为块级作用域,不允许重复声明。

块级作用域与函数作用域,任何一对花括号{}中的语句集都属于一个块,在里面定义的所有变量是代码外不可见的,即为块级作用域,函数作用域指在函数中的参数和变量在函数外部是不可见的。

2.class类(Class)

ES6中支持class语法,但他不是新的对象继承模型,他只是原型链的语法糖表现形式

class声明类

constructor定义构造函数初始化

extends继承父类

super调用父级构造方法

static定义静态方法和属性

父类方法可以重写

class Person {
  constructor() {
    console.log('hello');
  }
  work() {
    console.log('fight!!!');
  }
  static sleep() {
    console.log('~ZZZZZ');
  }
}
console.log(typeof Person);//function
let per = new Person();//hello
per.work();//fight!!!
Person.sleep();//~ZZZZZ

3.箭头函数(Arrow function)

不需要function关键字来创建函数

省略return关键字

this始终指向函数声明所在作用域下的this值

如果形参只有一个,小括号可以省略

函数体如果只有一个语句,花括号可以省略,函数返回值为该条语句的执行结果

箭头函数不能作为构造函数实例化

箭头函数不会更改this指向,适合用来指定回调函数

//es5
var fun = function() {}

//es6
var fun1 = () => {}

4.函数的参数默认值(Funtion parameter defaults)

函数传参可以有默认值

// es6
function person(name = '张三') {
  console.log(name);
}

5.模板字符串 ``(Template string)

可以使用反引号``来进行字符拼接,${}

6.解构赋值(Deatructuring assignment)

可以使用[]和{}来对数组和对象进行解构,

// 创建数组
const person = ['唐三藏', '孙悟空', '沙和尚'];
// 数组解构
const [per1, per2, per3] = person;

// 创建对象
const per = {
  name: '张三',
  age: 12,
  sex: '男',
};
// 对象解构
const { name, age, sex } = per;

7.模块化(Module)

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

好处:防止命名冲突,代码复用,高维护性

导入import,导出export default

export const area = (r) => PI * r ** 2

import { ... } from './name.js';

ES6之前的模块化规范有

1.CommonJS=》NodeJS\Browserify

2.AMD=>requireJS

3.CMD=>seaJS

8.Spread/Rest操作符(扩展操作符 ,Spread operator)

是指...,具体是Spread还是Rest要看上下文语境。

当用于迭代器中时,他是一个Spread操作符,迭代器(iterator)是按照一定顺序对一个或多个容器中的元素进行遍历的一种机制

function num(x, y, z) {
  console.log(x, y, z);
}

const num1 = [1, 2, 3];
num(...num1);

当用于函数传参时,是一个Rest操作符,当被用于函数传参,是一个Rest操作符

function num(...args) {
  console.log(args);
}

num(1,2,3);

9.promise

用于更优雅的处理异步请求,很好解决回调地狱的问题

Promise有三个状态,分别是:

1等待中(pending),

2完成了(resolved),

3拒绝了(rejected)

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

Promise的构造函数:Promise(excutor){}

Promise.prototype.then方法

Promise.prototype.catch方法

new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve('success');
  }, 1000);
})
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.log(err);
  });

10.for ... of

for .. of 语句在可迭代对象(array,map,set,string,typedarray,arguments对象等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

for of遍历的是键值对中的值

const person = ['唐三藏', '孙悟空', '沙和尚'];

for (let p of person) {
  console.log(p);
}

11.Symbol

新的基本数据类型,表示独一无二的值。类似于字符串的数据类型

特点:Symbol的值是唯一的,用来解决命名冲突的问题

Symbol值不能与其他数据进行运算

Symbol定义的对象属性不能使用for in循环遍历,但是可以用Reflect.ownKeys来获取对象的所有键名

// 创建Symbol
let s1 = Symbol();
console.log(typeof s1);//symbol
// 添加标识的Symbol
let s2 = Symbol('张三'); //括号里相当于注释
let s2_2 = Symbol('张三');
console.log(s2 == s2_2);//false
// 使用Symbol for定义
let s3 = Symbol.for('张三');
let s3_3 = Symbol.for('张三');
console.log(s3 === s3_3);//true

Symbol内置值

除了定义自己使用的Symbol值以外,ES6还提供11个内置的Symbol值,指向语言内部使用方法,可以称这些方法为魔术方法。因为他们会在特定的场景下自动执行

12.迭代器(Iterator)

遍历器(iterator)就是一种机制,它是一种接口。为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署了Iterator接口,就可以完成遍历操作

1.ES6创造了新的遍历命令for of循环,Iterator接口主要供for of消费

2.原生具备iterator接口的数据(可用for of 遍历

字符串String

数组array

映射map

集合set

argument对象

NodeList等DOM集合类型

3.工作原理

a创建一个指针对象,指向当前数据结构的起始位置

b第一次调用对象的next方法,指针自动指向数据结构的第一个成员

c不断调用next方法,指针一直往后移动。直到指向最后一个成员

d每调用next方法返回一个包含value和done属性的对象

13.生成器(Generator)

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同,之前解决异步编程的方法都是使用回调函数,它拥有在一个函数块内暂停和恢复代码执行的能力,生成器形式是一个函数,函数名称前面加个*表示它是一个生成器

生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句后的值

yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next方法,执行一段代码

next方法可以传递实参,作为yield语句的返回值

function* gen() {
  yield '1';
  yield '2';
  return '3';
}
let iterator = gen();
console.log(iterator.next()); //{ value: '1', done: false }
console.log(iterator.next()); //{ value: '2', done: false }
console.log(iterator.next()); //{ value: '3', done: true }

14.Set集合/WeakSet

ES6新的数据结构,存储任何类型的唯一值,即集合中所保存的元素是不重复的,类数组结构。

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

集合的属性和方法:

size返回集合的元素个数

add增加一个新元素,返回当前集合

delete删除元素,返回boolean值

has检测集合中是否包含某个元素,返回boolean值

clear清空集合,返回undefined

var num = [1, 2, 3];
let num1 = new Set(num); //Set(3) { 1, 2, 3 }

console.log(Array.from(num1));//[ 1, 2, 3 ]

类数组不是数组,要转化为数组Array.form(arrayNew),这样arrNew才是数组

WeakSet解构与Set类似 但区别有下:

1.WeakSet对象中只能存放对象引用,不能存在值,而Set对象都可以。

2.WeakSet对象中存储的对象值都是被弱引用的,如果没有其他的变量或属性引用这个对象值,则这个对象会被当成垃圾回收掉,因为这个原因,WeakSet对象无法被枚举。没有办法拿到它包含的所有元素。

var ws = new WeakSet()
var obj = {}
var foo = {}
​
ws.add(window)
ws.add(obj)
​
ws.has(window) // true
ws.has(foo)    // false, 对象 foo 并没有被添加进 ws 中 
​
ws.delete(window) // 从集合中删除 window 对象
ws.has(window)    // false, window 对象已经被删除了
​
ws.clear() // 清空整个 WeakSet 对象

15.map映射/WeakMap

ES6提供的数据结构,类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值包括对象都可以当作键,map实现了iterator接口,也可以使用扩展运算符和for of进行遍历

map属性和方法

size返回map的元素个数

set增加一个新元素,返回当前map

get返回键名对象的键值

has检测map中是否包含某个元素,返回boolean值

clear清空集合,返回undefined

// 创建一个空map
let m1 = new Map();
// 创建一个非空map
let m2 = new Map([
  ['name', '张三'],
  ['sex', '男'],
]);
console.log(m2.size); //2
console.log(m2.set('age', '13')); //Map(3) { 'name' => '张三', 'sex' => '男', 'age' => '13' }
console.log(m2.get('sex')); //男
console.log(m2.has('name')); //true
console.log(m2.clear()); //undefined

WeakMap对象是一组键/值对的集合,其中的键是弱引用的,其键必须是对象,而值可以是任意的,

跟Map的区别和Set和WeakSet区别相似

16.Proxy/Reflect

Proxy对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)

Reflect是一个内置的对象,他提供拦截javascript操作的方法,这些方法与Proxy方法相同,Reflect不是一个函数对象,因此不可构造

若对象带有configurable: false,跟writable: false属性,则代理失效

const observe = (data, callback) => {
      return new Proxy(data, {
            get(target, key) {
                return Reflect.get(target, key)
            },
            set(target, key, value, proxy) {
                  callback(key, value);
                  target[key] = value;
                    return Reflect.set(target, key, value, proxy)
            }
      })
}
​
const FooBar = { open: false };
const FooBarObserver = observe(FooBar, (property, value) => {
  property === 'open' && value 
          ? console.log('FooBar is open!!!') 
          : console.log('keep waiting');
});
console.log(FooBarObserver.open) // false
FooBarObserver.open = true // FooBar is open!!!

17.Regex对象的扩展

正则新增符号

i修饰符

/[a-z]/i.test('\u212A') // false
/[a-z]/iu.test('\u212A') // true

y修饰符

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;
​
r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]
​
r1.exec(s) // ["aa"]
r2.exec(s) // null

String.prototype.flags查看RegExp构造函数的修饰符

var regex = new RegExp('xyz', 'i')
regex.flags // 'i'

unicode模式

var s = ' '
/^.$/.test(s) // false
/^.$/u.test(s) // true

u转义

/\,/ // /\,/
/\,/u // 报错 没有u修饰符时,逗号前面的反斜杠是无效的,加了u修饰符就报错。

引用

const RE_TWICE = /^(?<word>[a-z]+)!\k<word>$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false
​
const RE_TWICE = /^(?<word>[a-z]+)!\1$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false

字符串方法的实现改为调用RegExp方法

  • String.prototype.match 调用 RegExp.prototype[Symbol.match]

  • String.prototype.replace 调用 RegExp.prototype[Symbol.replace]

  • String.prototype.search 调用 RegExp.prototype[Symbol.search]

  • String.prototype.split 调用 RegExp.prototype[Symbol.split]

18.正则新增属性

RegExp.prototype.sticky 表示是否有y修饰符

RegExp.prototype.flags 获取修饰符

19.Math对象的扩展

二进制和八进制

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

  • Number.EPSILON : 数值最小精度

  • Number.MIN_SAFE_INTEGER : 最小安全数值(-2^53)

  • Number.MAX_SAFE_INTEGER : 最大安全数值(2^53)

  • Number.parseInt() : 返回转换值的整数部分

  • Number.parseFloat() : 返回转换值的浮点数部分

  • Number.isFinite() : 是否为有限数值

  • Number.isNaN() : 是否为NaN

  • Number.isInteger() : 是否为整数

  • Number.isSafeInteger() : 是否在数值安全范围内

  • Math.trunc() : 返回数值整数部分

  • Math.sign() : 返回数值类型(正数1负数-1零0)

  • Math.cbrt() : 返回数值立方根

  • Math.clz32() : 返回数值的32位无符号整数形式

  • Math.imul() : 返回两个数值相乘

  • Math.fround() : 返回数值的32位单精度浮点数形式

  • Math.hypot() : 返回所有数值平方和的平方根

  • Math.expm1() : 返回e^n - 1

  • Math.log1p() : 返回1 + n的自然对数(Math.log(1 + n))

  • Math.log10() : 返回以10为底的n的对数

  • Math.log2() : 返回以2为底的n的对数

  • Math.sinh() : 返回n的双曲正弦

  • Math.cosh() : 返回n的双曲余弦

  • Math.tanh() : 返回n的双曲正切

  • Math.asinh() : 返回n的反双曲正弦

  • Math.acosh() : 返回n的反双曲余弦

  • Math.atanh() : 返回n的反双曲正切

20.Array对象的扩展

Array.prototype.from:转换具有Iterator接口的数据结构为真正数组,返回新数组

Array.prototype.of():转换一组值为真正数组,返回新数组

Array.prototype.copyWithin(),把指定位置的成员赋值到其他位置,返回原数组

Array.prototype.find():返回第一个符合条件的成员

Array.prototype.findIndex():返回第一个符合条件的成员索引值

Array.prototype.keys():返回以索引值为遍历器的对象

Array.prototype.fill():根据指定值填充整个数组

Array.prototype.values(): 返回以属性值为遍历器的对象

Array.prototype.entries(): 返回以索引值和属性值为遍历器的对象

数组空位:ES6明确将数组空位转为undefined或者empty

20.5.对象扩展

ES6新增了一些Object对象方法

Object.is比较两个值是否严格相等,与[===],行为基本一致(+0与NaN)

Object.assign对象的合并,将源对象的所有可枚举属性,复制到目标对象

proto,setPrototypeOf,setPrototypeOf可以直接设置对象的原型

ES7(ES2016)

21.Array.prototype.includes()

includes()方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false

const array1 = [1, 2, 3]
console.log(array1.includes(2)) // true
​
const pets = ['cat', 'dog', 'bat']
console.log(pets.includes('cat')) // true
console.log(pets.includes('at')) // false

22.幂运算符**

具有与Math.pow()一样的功能

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

23.模板字符串

自ES7起,带标签的模板字符串遵守以下转义序列的规则:

  • Unicode字符以"\u"开头,例如\u00A9

  • Unicode码位用"\u{}"表示,例如\u{2F804}

  • 十六进制以"\x"开头,例如\xA9

  • 八进制以""和数字开头,例如\251

ES2017

24.异步函数async/await

比promise更好的解决回调地狱

async fun(){
    await fn()
}

让我们使用起来像同步的语法来编写异步代码

25.Object.values()

返回一个数组,其中包含给定对象的所有可枚举字符串键属性的值。

26.Object.entries()

返回一个数组,其中包含给定对象的所有可枚举字符串键属性的键值对,每对都被编码为一个二进制数组。

27.字符串填充:字符串方法.padStart(),.padEnd()

.padStart(),.padEnd()插入填充文本,直到接收者足够长:

 '7'.padStart(3, '0')//'007'

 'yes'.padEnd(6, '!')//'yes!!!'

28.函数参数列表和调用中的尾随逗号

自ES3以来,数组文字和自ES5以来对象文字中都允许使用尾随逗号,它们现在也允许在函数调用和方法调用中使用。

ES2018

29异步迭代

是同步迭代的异步版本,基于Promise

使用同步迭代,我们可以立即访问每个项目,使用异步迭代,我们必须await在访问项目之前。

对于同步迭代,我们使用for -of循环,对于异步迭代,我们使用for-await-of循环。

30.Spread到对象文字中

通过在对象文字中使用Spread(...),可以将另一个对象的属性复制到当前对象中,创建对象的浅拷贝obj;

const shallowCopy = {...obj};

31.解构

当对象解构一个值时,我们现在可以使用(...)来获取一个对象中所有以前未提及的属性。

const {a, ...remaining} = {a: 1, b: 2, c: 3};
assert.deepEqual(remaining, {b: 2, c: 3});

32.Promise.prototype.finally()

与finally try-catch-finally语句的子句相关

换句话说:.finally()无论Promise是否被履行或拒绝,都会执行回调

33.新的正则表达式功能

RegExp命名捕获组:除了按编号访问组之外,我们现在可以命名它们,并按名称访问它们:

const matchObj = '---756---'.match(/(?<digits>[0-9]+)/)
assert.equal(matchObj.groups.digits, '756');

RegExp后视断言补充了前瞻断言:

  • 正向后视:(?<=X)如果当前位置前面有 ,则匹配'X'

  • Negative lookbehind:(?<!X)如果当前位置前面没有 ,则匹配'(?<!X)'

s(dotAll)正则表达式标志,如果此标志处于活动状态,则点匹配行终止符(默认情况下不匹配)。

const re = /foo.bar/s;  //  等价于 const re = new RegExp('foo.bar', 's');
re.test('foo\nbar');    // true
re.dotAll;      // true
re.flags;       // "s"

RegExpUnicode属性转义在匹配Unicode代码点集时为我们提供更多功能

 /^\p{Lowercase_Letter}+$/u.test('aüπ')//true

 /^\p{White_Space}+$/u.test('\n \t')//true

 /^\p{Script=Greek}+$/u.test('ΩΔΨ')//true

34.模板文字修订

允许在标记模板中带有反斜杠的文本在字符串文字中是非法的:

windowsPath`C:\uuu\xxx\111`
latex`\unicode`

ES2019

35.Array.flatMap()

使用方式类似.map(),但让回调返回零个或多个值的数组,而不是单个值,然后将数组链接起来并作为.flatMap()的返回结果,

用例包括:

同时过滤和映射,将单个输入值映射到多个输出值

36.Array.flat()

将嵌套数组转换为平面数组,或者,我们可以告诉它应该在哪个嵌套深度停止展平。

37.Object.fromEntries()

从可迭代的条目创建一个对象,每个条目都是一个包含属性和属性值的两元素数组。

38.字符串方法

.trimStart()工作方式 .trimEnd()类似.trim(),但仅在字符串的开投或结尾删除空格。

39.可选catch绑定catch:

如果我们不使用它,我们现在可以省略子句的参数

40.Symbol.prototype.deacription

读取Symbol的描述,以前,描述包含在结果中,.toString()无法单独访问。

ES2020

41.新模块功能

动态导入via import():

正常的import语句是静态的:我们只能在模块的顶层使用它,他的模块说明符是一个固定的字符串,import()改变了这一点,它可以在任何地方使用(包括条件语句),我们可以计算它的参数。

import.meta包含当前模块的元数据,他的第一个广泛支持的属性是import.meta.url包含一个带有当前模块文件URL的字符串。

命名空间重新导出:以下表达式导入'mod'命名空间对象中模块的所有导出ns并导出该对象。

export * as ns from ‘mod’;

42.属性访问和方法调用的可选连接

示例:value.?prop

此表达式的计算结果 如果 value 是 undefined 或null ,为undefined,

否则计算结果为 value.prop,当某些属性可能丢失时,此功能在属性读取链中特别有用。

43.空值合并运算符(??)

value ?? defaultValue

这个表达式是如果value为undefined或null,value为DefaultValue,该运算符允许我们在缺少某些内容时使用默认值

以前在这种情况下使用了逻辑或运算符||,但是这里有缺点,因为只要左侧是false的(这并不总是正确的),他就会返回默认值。

44.Bigints任意精度整数

Bigints是一种新的原始类型,它支持可以任意大的整数(它们的存储会根据需要增长)。

45.String.prototype.matchAll()

如果未设置标志,则此方法抛出,并返回一个包含给定字符串的所有匹配对象的课迭代对象。

46.Promise.allSettled()

接收一个可迭代的Promises.它返回一个Promise,一旦所有输入的Promise都被解决,该Promise就会实现,实现值是一个数组,每个输入Promise有一个对象

{ status: 'fulfilled', value: «fulfillment value» }

{ status: 'rejected', reason: «rejection value» }

47.globalThis

提供了一种访问全局对象的方法,该对象可在浏览器和服务器平台(如Node.js)上运行。

48.for in

for in遍历的是键值对中的键

ES2021

49.String.prototype.replaceAll()

让我们替换正则表达式或字符串的所有匹配项

.replace()仅替换第一次出现的字符串

'abbbaab'.replaceAll('b', 'x')//'axxxaax'

50.Promise.any()和AggregateError

Promise.any()返回一个Promise,一旦Promise的可迭代中的第一个Promise完成,他就会完成,如果只有拒绝,则将它们放入AggregateError成为拒绝值的其中

Promise.any()只对几个中第一个实现的Promise fullfilled时使用。

51.逻辑赋值运算符

a ||= b;

a &&= b;

a ??= b;

52.下划线_作为分隔符

数字文字:123_456.789_012

Bigint字面量:6_000_000_000_000_000_000_000_000n

53.WeakRefs

允许创建对象的弱引用。这样就能够在跟踪现有对象时不会阻止对其进行垃圾回收,对于缓存和对象映射非常有用。

ES2022

54.静态初始化块

类静态块提议提供了一种优雅的方式,在类声明/定义期间评估静态初始化代码块,可以访问类的私有字段。

55.私有字段检查

#privateSlot in obj 检查是否obj有私有插槽#privateSlot

56.Top-level await

我们现在可以在模块await顶层使用,而不必再输入异步函数或方法

57.error.causeError

及其子类现在让我们指定哪个错误导致了当前错误

new Error(‘Something went wrong“),{cause: otherError})

58.at()可索引值的方法

让我们可以读取给顶索引处的元素(如括号运算符[])并支持负索引(与括号运算符不同)

 ['a', 'b', 'c'].at(0)
//'a'
 ['a', 'b', 'c'].at(-1)
//'c'

可索引类型可使用方法.at()

string,Array,所有类型化数组类:Uint8Array等。

59.RegExp匹配索引

如果我们向正则表达式添加一个标志/d,使用它会生成匹配对象,记录每个组捕获的开始和结束索引。

60.Object.hasOwn(obj,propKey)

提供了一种安全的方法来检查对象obj是否具有带有key的自己的属性propKey,与相比Object.prototype.hasOwnProperty,它适用于所有对象。简单将就是用来替代Object.prototype.hasOwnProperty.call()

61.声明类的字段

类字段可以在类顶层被定义和初始化

class Post{

    title;

    content;

    shares = 0;

}

62.私有方法和字段

用#前缀来定义类的私有方法和字段

class User{

    name;

    #password;

    get #password(){

        return #password;

    }

}

63.类的静态公共方法和字段

在之前的类的字段和私有方法提案基础上,增加静态公共字段、静态私有方法和静态私有字段的特性

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值