ES7-ES12的学习

218 阅读4分钟

ES7-ES12的学习

ES7

数组的includes()

let arr = ['aaa', 'bbb', 'ccc', 'ddd', NaN]
if(arr.indexOf('aaa') !== -1) {
  console.log('存在aaa元素~');
}

// 参数二: 从那个元素开始
console.log(arr.includes('ddd', 2)) // true

// 通过indexOf,不能判断NaN是否存在
// 可以使用 [].includes() 来判断NaN是否存在.
console.log(arr.includes(NaN)) // true

指数运算符

// 2的3次方

console.log(Math.pow(2, 3)) // 8

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

ES8

Object.values()

var obj = {
  name: 'Fhup',
  age: 18
}
// 获取对象所有的值
console.log(Object.values(obj));


console.log(Object.values('abc')) // [ 'a', 'b', 'c' ]

Object.entries()

var obj = {
  name: 'Fhup',
  age: 18
}

console.log(Object.entries(obj)) // [ [ 'name', 'Fhup' ], [ 'age', 18 ] ]

// for(const item of Object.entries(obj)) {
//   console.log(item[0], item[1]);
// }
for(const [key, value] of Object.entries(obj)) {
  console.log(key ,value);
}


console.log(Object.entries(['aaa', 'bbb', 'ccc']))
console.log(Object.entries('abc'))

padStart()和padEnd()

let str = 'fhupyyds'

// pad: 填充
let padStr = str.padStart(15, '*').padEnd(20, '*')
console.log(padStr) // *******fhupyyds*****

// 案例
const cardNumber = '159753123456252514'
// 1.替换方案
// const sliceCard = cardNumber.slice(0,5)
// const newCard = cardNumber.replace(sliceCard, '*********')

// 2.pad方案
const sliceLastCard = cardNumber.slice(-4)
const newCard = sliceLastCard.padStart(cardNumber.length, '*')
console.log(newCard) // **************2514

函数参数多加逗号问题

// ES8之前,不允许在函数参数后多加逗号
function foo(m, n,) {
  console.log(m, n)
}

foo(1, 2,)

// 了解就行

ES10

数组的flat和flatMap

// 1.flat对数组进行降维(扁平化处理)
const nums = [10, 20, [3, [33, 66, 99], 9], [1, 1], 30, 66]

const newNums = nums.flat() // 深度默认值为1 (depth?: 1)
console.log(newNums);
// 在降维一次,或者直接传入 depth: 2

/**
 * 2.flatMap的使用
 * 映射函数先映射每个元素,将其压缩为一个新数组. 
 * 执行步骤> 先进行数组的map操作,在做flat操作, flatmap的深度为 1
 */
const arrs = [1, [2, 3], 4, [5, [6, 7, 8], 9], 10]
// flatMap 和 [].map() 使用方式一样, 必须传入 callable
const newArrs = arrs.flatMap(item => {
  return item
})
console.log(newArrs);


// 3.flatMap的应用场景
const messages = ['hello world', 'hello xxx', 'my name is Fhup']
const words = messages.flatMap(item => {
  return item.split(' ') // map之后: [ ['hello', 'world'], ['hello', 'xxx'] ], flat之后 [ 'hello' ... ]
})
console.log(words);

Object.fromEntries()

const obj = {
  name: 'Fhup',
  age: 18
}
const entries = Object.entries(obj) // 将对象转为entries类型
// console.log(entries) // [ [ 'name', 'Fhup' ], [ 'age', 18 ] ]


// 1.Object.fromEntries()将entries转为对象类型
let newObj = Object.fromEntries(entries)
// console.log(newObj) // { name: 'Fhup', age: 18 }


// Object.fromEntries()的应用场景
const queryString = 'name=Fhup&age=18&height=1.88'
const queryParams = new URLSearchParams(queryString)
// console.log(queryParams) // URLSearchParams { 'name' => 'Fhup', 'age' => '18', 'height' => '1.88' }

console.log(Object.fromEntries(queryParams));

字符串的trimStart()和trimEnd()

let str = '     aaa bbb    '

// console.log(str.length) // 16
// var trimStr = str.trim()
// console.log(trimStr.length) // 7


// ES10新增的 字符串的trimStart() 和 trimEnd() 
var trimS = str.trimStart()
console.log(trimS);
console.log(trimS.length);

var trimE = str.trimEnd()
console.log(trimE);
console.log(trimE.length);

ES11

大整数BigInt的使用

// 早期的js中,不能正确的表示过大的数字(ES11之前)
const maxInt = Number.MAX_SAFE_INTEGER // 最大且安全的integer值
console.log(maxInt) // 9007199254740991

// 不安全,有些值变得不正确
console.log(maxInt + 1)
console.log(maxInt + 2)

// ES11之后: BigInt: +n
const bigInt = 900719925474099100n
console.log(bigInt);

// console.log(bigInt + 10); // 报错. 大值加小值,不进行隐式转换
// 解决方案: 
// 1.小值加上n就可以了
console.log(bigInt + 10n);
// 2.使用BigInt(number)方法
console.log(bigInt + BigInt(10));

// 把大值转换为小值
const smallNum = Number(bigInt)
console.log(smallNum) // 大转小有时候不安全(不正确)

空值合并运算??

// 空值合并运算 ??
const foo = 0
// const bar = foo || 'default value' 
// || (对0和空字符串失效),foo = 0时,bar = 'default value'

// ES11 提供 ?? 运算符 (对0和空字符串进行处理)
const bar = foo ?? 'default value' // 是undefined/null时,使用后面的默认值

console.log(bar)

可选链

// ES11 可选链 ?.
// 作用: 进行null/undefined判断时更加清晰和简洁
const info = {
  name: 'Fhup',
  // friend: {
  //   name: 'xxx',
  //   girlFriend: {
  //     name: 'cjk'
  //   }
  // }
}
console.log(info.friend?.girlFriend?.name) // friend? 判断friend有没有,没有返回undefined

获取全局对象globalThis

// 获取某一环境下的全局对象(Global Object)

// 浏览器中 this为window
// console.log(this);
// console.log(window);

// Node下
// console.log(this) // {}
// console.log(global)

// ES11 提供了 globalThis
console.log(globalThis) // 浏览器为window,node下为global

for-in操作的标准化

var obj = {
  name: 'Fhup',
  age: 18
}
// ES11规范,for...in遍历出来的item为key
for(let item in obj){
  console.log(obj[item])
}

ES12

FinalizationRegistry

// ES12(ES2021): FinalizationRegistry 这是一个类,传入一个callback
// FinalizationRegistry 对象可以让你在对象被垃圾回收时请求一个回调.
const fr = new FinalizationRegistry((value)=>{ // value的值是在注册时传入的
  console.log('注册在FinalizationRegistry上的对象被销毁了~', value)
})

let obj = { name: 'Fhup' }
let info = { age: 18 }

fr.register(obj, 'obj对象')
fr.register(info, 'info对象')

obj = null
info = null

// GC会不定时的来回收垃圾

WeakRef的使用

// ES2021: 新增WeakRef(),这是一个类
// WeakRef创建的对象是一个弱引用
const fr = new FinalizationRegistry( (value) => {
  console.log(value ,'对象被销毁~');
})
let obj = {
  age: 18
}
// let info = obj // 强引用,obj不会被销毁 obj->{age:18} info->{age:18}
let info = new WeakRef(obj) // 弱引用

fr.register(obj, 'obj')

obj = null

// WeakRef.prototype.deref(),返回当前实例的WeakRef对象所绑定的target对象.
setTimeout(() => {
  console.log(info.deref()?.age)
  console.log(info.deref() && info.deref().age);
}, 10000)

逻辑赋值运算

// 1. ||= 逻辑或赋值运算
let message = undefined
// message = message || 'default'
message ||= 'default'
console.log(message);

// 2. &&= 逻辑与赋值运算(不常用)
let obj = {
  foo(){
    console.log('foo');
  }
}
obj.foo && obj.foo()

// 3. ??= 逻辑空赋值运算
let info = 0
// info = info ?? 'default'
info ??= 'default'
console.log(info);

// !! 将其他类型转为Boolean
console.log(!!123); // true
console.log(Boolean(123))