1.#号的使用
//在class中用#号来声明私有变量
class Counter {
#number = 10
increment() {
this.#number++
}
getNum() {
return this.#number
}
}
const counter = new Counter()
counter.increment()
console.log(counter.getNum()) //11
console.log(counter.#number)
2.空值运算符
let a= b||2313
let a=b??1321
3.访问对象扩展运算符
et name = user?.info?.name;
let age = user?.info?.getAge?.();
4.inport的动态,静态的使用方法//静态static 动态dynamic//静态的不带()动态的带()
static import: import xxx from 'xxx' //有声明提升,一般只放在头部位置
dynamic import(): const xxx = import('xxx') //可以放在任何位置
在 import() 之前,当我们需要根据条件导入模块时,不得不使用 require()
if(XXX) {
const menu = require('./menu');
}
现在可以替换为
if(XXX) {
const menu = import('./menu');
}
import.meta 会返回一个对象,有一个 url 属性,返回当前模块的url路径,只能在模块内部使用。
/main.js
console.log(import.meta); //{url: "http://localhost:8080/main.js"} PS:使用了 http-server 启动
5.globalThis
globalThis 提供了一个标准的方式去获取不同环境下的全局对象。它不像 window 或者 self 这些属性,而是确保可以在有无窗口的环境下都可以正常工作。所以你可以安心的使用 globalThis ,不必担心它的运行环境
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
var globals = getGlobal();
if (typeof globals.setTimeout !== 'function') {
// no setTimeout in this environment!
}
//有了 globalThis 之后,只需要:
if (typeof globalThis.setTimeout !== 'function') {
// no setTimeout in this environment!
}
6.数组的解构
1.定义变量名的地方修改为一个方括号 方括号中填写需要存放数据的变量名 根据位置分配数组所对应数值
const [foo,bar,baz] = arr
2.添加三个点表示提取从当前位置开始往后的所有成员 只能在最后一个成员中使用
const [foo,...rest] = arr
3.提取成员小于数组 只会取从前往后的数值 如果大于 就为undefined
4.可以提供默认值
const [more='default value] = arr
5.使操作数据变得简单
const path = '/fpp/bar/baz'
const [,rootdir] = path.split('/')
7.对象的结构
1.根据属性名去匹配 提取
const obj = {name:'zce',age:'18'}
const {name} = obj // 'zce'
2.可更改名字 避免冲突
const {name:objName} = obj
3.设置默认值
const {name:objName = 'jack'} = obj
const {log} = console
log('foo')
8.字符串的方法
1.includes() //是否包含
2.startsWith() //开头是否包含
3.endsWith() //结尾是否包含
9.以数组的形式代替函数的 arguments属性
function foo(...args){ console.log(args) }
10.数组展开符
console.log(...arr)
11.将多个源对象里面的数据复制到一个对象中
const source1 = {
a:123,
b:123
}
const target = {
a:456,
c:456
}
const result = Object.assign(target,source1)
console.log(target) // {a:123,c:465,b:123}
//注:对象的字段名一样时,后者会覆盖前者
12.专门判断nan Object.is
0 == false
0 === false
Object.is(0,false)
Object.is(NaN,NaN)
// true NaN === NaN //false
12.获取对象的所有属性值
let a={
name:'张三',
age:18,
sex:'男'
}
console.log(Reflect.ownKeys(a));
注:与Object.keys//效果一样
//Object.values 是获取到所有对象的键值
13.类的继承 extends 实现继承的字段
class Student extends Person{
constructor(name,number){
super(name)
this.number = number
}
hello(){
super.say()
console.log(`my school number is ${this.number}`)
}
}
const s = new Student('jack','100')
s.hello()
14.Set 数据结构
1.
add //添加数据的方法
2.
delete //删除数据的方法
3.
has 判断set数据中有没有这个数据
4.
clear 清除set集合里面的数据
const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
console.log(s) // Set {1,2,3,4}
s.forEach(i => console.log(i))
console.log(s.size)
console.log(s.has(100))
console.log(s.delete(3))
s.clear()
const arr = [1,2,3,4]
const result = [...new Set(arr)] //快速转化为一个新的数组
15.map数据对象
const m = new Map()
const tom = {name:'tom'}
m.set(tom,90)
console.log(m) // Map {{name:'tom'} => 90}
可以将任何数据作为对象的键值(key)
而通常的写法会自动转化为字符串的格式
const obj = {}
obj[{a:1}] = 'value' // obj['[Object Object]'] = 'value'
16.symbol
1.一种全新的原始数据类型 唯一的 避免属性名冲突
比如:一个对象要合并一个新的对象 但不知道其中是否有同名的情况
let obj={
name:'32131'
}
obj[Symbol("张三")]='55579'
obj[Symbol("张三")]='887912'
console.log(obj);
2.建立私有成员
const name = Symbol()
const person = {
[name]:'zce',
say(){
console.log(this[name])
}
}
// 外部没办法创建一个相同的Symbol
// person[Symbol()]
person.say() //只能调用这个普通对象的成员
3.改变toString()默认标签
const obj = {
[Symbol.toStringTag]:'XObject'
}
console.log(obj.toString()) // [object XObject]
4.获取Symbol 属性名
Object.getOwnPropertySymbols(obj) // 获取Symbol属性名
Object.keys(obj) 只能获取对象字符串属性名
17.es中的循环比较
1.for比较适合普通的数组
2.for .. in 比较适合便利对象
3.forEatch,map 是函数式的便利方法
4.for...of可以便利任何数据
18 生成器//主要是用于异步编程中嵌套
function * foo(){
console.log('111')
yield 100 // 遇到yield暂停
console.log('222')
yield 200
console.log('333')
yield 300
}
const generator = foo() // 自动返回一个生成器对象
console.log(generator.next()) // 111 {value:100,done:false}
console.log(generator.next()) // 222 {value:200,done:false}
console.log(generator.next()) // 333 {value:300,done:false}
19.指数运算
Math.pow(2,10) //指数运算返回 x 的 y 次幂的值即2的10次方
20.将对象转换成数组 使用Object.entries方法//返回一个二维数组
let obj={
name:'展示柜',
age:18
}
console.log(Object.entries(obj))
let students = {
amelia: 20,
beatrice: 22,
cece: 20,
deirdre: 19,
eloise: 21}
// convert to array in order to make use of .filter() functionlet overTwentyOne = Object.entries(students).filter(([name, age]) => {
return age >= 21}) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]
// turn multidimensional array back into an objectlet DrinkingAgeStudents = Object.fromEntries(overTwentyOne);
// { beatrice: 22, eloise: 21 }
需要注意的一点是,使用Object.fromEntries会把Object中的重复key覆盖掉,只保存最后一个,
let students = [
[ 'amelia', 22 ],
[ 'beatrice', 22 ],
[ 'eloise', 21],
[ 'beatrice', 20 ]]
let studentObj = Object.fromEntries(students);
// { amelia: 22, beatrice: 20, eloise: 21 }// dropped first beatrice!
19.数组concat方法
合并两个数组
let a=[[1,2],[3,4]]
let b=[1,2]
let arr1=a.concat(b)
console.log(arr1)
20.数组的 降维
let a=[[1,2],[3,4]]
let b=a.flat(1)
console.log(b)
注:flat指定参数和不指定参数是一样的,
对于不知道数组的维度时使用 Infinity参数来实现降维度,知道数组的维度时慎用,尽量不用
21.flatMap
flatMap 等价于map 和 flat不加参数的结合体,所以flatMap 只展开一层数组。
let grades = [78, 62, 80, 64]
let curved = grades.map(grade => [grade, grade + 7])// [ [ 78, 85 ], [ 62, 69 ], [ 80, 87 ], [ 64, 71 ] ]
let flatMapped = [].concat.apply([], curved) // now flatten, could use flat but that didn't exist before either// [// 78, 85, 62, 69,// 80, 87, 64, 71// ]
flatMap进阶版
let grades = [78, 62, 80, 64]
let flatMapped = grades.flatMap(grade => [grade, grade + 7]);// [// 78, 85, 62, 69,// 80, 87, 64, 71// ]
由于是map 和 flat不加参数的结合体,flatMap 只展开一层数组:
22.去除字符串两端的空格
String.trimStart 和 String.trimEnd
等价于之前的String.trimRight 和 String.trimLeft
let message = " Welcome to CS 101 "
message.trimRight()
// ' Welcome to CS 101'
message.trimLeft()
// 'Welcome to CS 101 '
message.trimRight().trimLeft()
// 'Welcome to CS 101'
等价于
let message = " Welcome to CS 101 "
message.trimEnd()
// ' Welcome to CS 101'
message.trimStart()
// 'Welcome to CS 101 '
message.trimEnd().trimStart()
// 'Welcome to CS 101'
23.try …catch 的升级
try {
let parsed = JSON.parse(obj)} catch(e) {
// ignore e, or use
console.log(obj)}
e可以不写
try {
let parsed = JSON.parse(obj)} catch {
console.log(obj)}
24.toString()更新
之前的版本中,Function.toString()直接把空格去掉了
function greeting() {
const name = 'CSS Tricks'
console.log(`hello from ${name}`)}
greeting.toString()//'function greeting() {\nconst name = \'CSS Tricks\'\nconsole.log(`hello from ${name} //`)\n}'
但是在es2019的版本中会完全保留空格
function greeting() {
const name = 'CSS Tricks'
console.log(`hello from ${name}`)}
greeting.toString()// 'function greeting() {\n' +// " const name = 'CSS Tricks'\n" +// ' console.log(`hello from ${name}`)\n' +// '}'
25.正则表达式命名捕获组(Regular Expression Named Capture Groups)
JavaScript正则表达式可以返回一个匹配的对象——一个包含匹配字符串的类数组,例如:以YYYY-MM-DD的格式解析日期:
const reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match[1], // 2018
month = match[2], // 04
day = match[3]; // 30
ES2018允许命名捕获组使用符号?,在打开捕获括号(后立即命名,示例如下
const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match.groups.year, // 2018
month = match.groups.month, // 04
day = match.groups.day; // 30
命名捕获在replace()方法中。例如将日期转换为美国的 MM-DD-YYYY 格式:
const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
d = '2018-04-30',
usDate = d.replace(reDate,
'$<month>-$<day>-$<year>');
25.正则表达式dotAll模式
/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
26.正则表达式 Unicode 转义
到目前为止,在正则表达式中本地访问 Unicode 字符属性是不被允许的。ES2018添加了 Unicode 属性转义——形式为\p{…}和\P{…},在正则表达式中使用标记 u (unicode) 设置,在\p块儿内,可以以键值对的方式设置需要匹配的属性而非具体内容
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('π'); // true
- matchAll
matchAll() 方法返回一个包含所有匹配正则表达式的结果的迭代器。使用 for...of 遍历或者使用 操作符 ... Array.from 将其转换成数组。
const reg = /[0-3]/g;
const data = '2020';
console.log(data.matchAll(reg));//data.matchAll 的返回值是一个迭代器
console.log([...data.matchAll(reg)]);
/**
* 0: ["2", index: 0, input: "2020", groups: undefined]
* 1: ["0", index: 1, input: "2020", groups: undefined]
* 2: ["2", index: 2, input: "2020", groups: undefined]
* 3: ["0", index: 3, input: "2020", groups: undefined]
*/