ES7 - Array Includes
在ES7之前,如果我们想判断一个数组中是否包含某个元素,需要通过 indexOf 获取结果,并且判断是否为 -1。
在ES7中,我们可以通过includes来判断一个数组中是否包含一个指定的元素,根据情况,如果包含则返回 true,否则返回false。
ES7 –指数exponentiation运算符
在ES7之前,计算数字的乘方需要通过 Math.pow 方法来完成。
在ES7中,增加了 ** 运算符,可以对数字来计算乘方
ES8 Object values
之前我们可以通过 Object.keys 获取一个对象所有的key
在ES8中提供了 Object.values 来获取所有的value值:
ES8 Object entries
通过 Object.entries 可以获取到一个数组,数组中会存放可枚举属性的键值对数组。
- 可以针对对象、数组、字符串进行操作;
ES8 - String Padding
某些字符串我们需要对其进行前后的填充,来实现某种格式化效果,ES8中增加了 padStart 和 padEnd 方法,分别是对字符串的首尾进行填充的。
我们简单具一个应用场景:比如需要对身份证、银行卡的前面位数进行隐藏:
ES8 - Trailing Commas
在ES8中,我们允许在函数定义和调用时多加一个逗号:
ES8 - Object Descriptors
Object.getOwnPropertyDescriptors :
Async Function:async、await
ES9新增知识点
Async iterators
Object spread operators
Promise finally
ES10 - flat flatMap
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
- 注意一:flatMap是先进行map操作,再做flat的操作;
- 注意二:flatMap中的flat相当于深度为1;
// 1.flat的使用
// 将一个数组,按照指定的深度遍历,将遍历到的元素和子数组组成一个新的数组,进行返回
const nums = [
12,
22,
[111, 222],
[333, 444],
[
[123, 321],
[231, 321],
],
];
const newNul1 = nums.flat(1);
console.log(newNul1);
const newNul2 = nums.flat(2);
console.log(newNul2);
// 2.flatMap的使用
// 1.对数组中每一个元素应用一次传入的map对应的函数
const message = ["hello world", "Hello What", "你好 世界"];
// 自己的方式: for循环
/* const newInfos = [];
for (const item of message) {
const infos = item.split(" ");
console.log(infos);
for (const info of infos) {
newInfos.push(info);
}
}
console.log(newInfos); */
// 先进行map,在进行flat操作
/* const newMessages = message.map((item) => item.split(" "));
const finalMessages = newMessages.flat(1);
console.log(finalMessages); */
// 3.flatMap
const finalMessages = message.flatMap((item) => item.split(" "));
console.log(finalMessages);
ES10 - Object fromEntries
在之前,我们可以通过 Object.entries 将一个对象转换成 entries
那么如果我们有一个entries了,如何将其转换成对象呢?
- ES10提供了 Object.formEntries来完成转换:
那么这个方法有什么应用场景呢?
// 1.对象
const obj = {
name: "why",
age: 18,
height: 1.77,
};
const entries = Object.entries(obj);
const info = Object.fromEntries(entries);
console.log(info);
// 2.应用
const searchString = "?name=why&age=14&height=1.66";
const params = new URLSearchParams(searchString);
console.log(params.get("name"));
console.log(params.get("age"));
console.log(params.entries());
/* for (const item of params.entries()) {
console.log(item);
} */
const paramsObj = Object.fromEntries(params);
console.log(paramsObj);
ES10 - trimStart trimEnd
去除一个字符串首尾的空格,我们可以通过trim方法,如果单独去除前面或者后面呢?
- ES10中给我们提供了trimStart和trimEnd
ES10 其他知识点
Symbol description
Optional catch binding
ES11 - BigInt
在早期的JavaScript中,我们不能正确的表示过大的数字:
- 大于MAX_SAFE_INTEGER的数值,表示的可能是不正确的。
那么ES11中,引入了新的数据类型BigInt,用于表示大的整数:
- BigInt的表示方法是在数值的后面加上n
ES11 - Nullish Coalescing Operator
ES11,Nullish Coalescing Operator增加了空值合并操作符:
let info = 0;
/* info = info || "默认值";
console.log(info); */
info = info ?? "默认值";
console.log(info);
ES11 - Optional Chaining
可选链也是ES11中新增一个特性,主要作用是让我们的代码在进行null和undefined判断时更加清晰和简洁:
const obj = {
name: "what",
friend: {
name: "rick",
running: function () {
console.log(this.name);
},
},
};
// obj.friend.running(); 直接调用
/*
if判断
if(obj.friend&&obj.friend.running){
obj.friend.running();
} */
// 可选链
obj?.friend?.running?.();
ES11 - Global This
在之前我们希望获取JavaScript环境的全局对象,不同的环境获取的方式是不一样的
- 比如在浏览器中可以通过this、window来获取;
- 比如在Node中我们需要通过global来获取;
在ES11中对获取全局对象进行了统一的规范:globalThis
ES11 - for…in标准化
在ES11之前,虽然很多浏览器支持for…in来遍历对象类型,但是并没有被ECMA标准化。
在ES11中,对其进行了标准化,for…in是用于遍历对象的key的:
ES11 其他知识点
Dynamic Impor
Promise.allSettled
import meta
ES12 - FinalizationRegistry
FinalizationRegistry 对象可以让你在对象被垃圾回收时请求一个回调。
- FinalizationRegistry 提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer );
你可以通过调用register方法,注册任何你想要清理回调的对象,传入该对象和所含的值;
let obj = { name: "why", age: 18 };
let info = { name: "what", age: 17 };
const finalRegistry = new FinalizationRegistry((value) => {
console.log("对象被回收了", value);
});
finalRegistry.register(obj, "why");
finalRegistry.register(info, "what");
// obj = null;
info = null;
ES12 - WeakRefs
如果我们默认将一个对象赋值给另外一个引用,那么这个引用是一个强引用:
- 如果我们希望是一个弱引用的话,可以使用WeakRef;
let info = { name: "why", age: 18 };
let obj = new WeakRef(info);
let obj2 = new WeakRef(info);
const finalRegistry = new FinalizationRegistry((value) => {
console.log("对象被回收了", value);
});
finalRegistry.register(info, "info");
/*
不要这样写,这样拿到之后又赋值会产生强引用
const infoRef = obj.deref();
console.log(infoRef);
console.log(infoRef.name, infoRef.age); */
setTimeout(() => {
info = null;
}, 2000);
setTimeout(() => {
console.log(obj.deref().name, obj.deref().age);
}, 8000);
ES12 - logical assignment operators
// 赋值运算符
const foo = "foo";
let counter = 100;
counter += 50;
// 逻辑赋值运算符
function foo2(message) {
// message = message || "默认值";
// message ||= "默认值";
// message = message ?? "默认值";
message ??= "默认值";
console.log(message);
}
foo2("abc");
foo2(0);
// && 逻辑赋值运算符
let obj = {
name: "what",
running: function () {
console.log("running~");
},
};
// 一般应用场景
// obj && obj.running && obj.running();
obj = obj && obj.name;
obj &&= obj.name;
console.log(obj);
ES12其他知识点
Numeric Separator
String.replaceAll
const message = "my name is what, what age is 19";
// const newMessage = message.replace('what','why')
const newMessage = message.replaceAll("what", "why");
console.log(newMessage);
ES13 - method .at()
字符串、数组的at方法,它们是作为ES13中的新特性加入的:
ES13 - Object.hasOwn(obj, propKey)
Object中新增了一个静态方法(类方法): hasOwn(obj, propKey)
- 该方法用于判断一个对象中是否有某个自己的属性;
那么和之前学习的Object.prototype.hasOwnProperty有什么区别呢?
- 区别一:防止对象内部有重写hasOwnProperty
- 区别二:对于隐式原型指向null的对象, hasOwnProperty无法进行判断
const obj = {
name: "why",
age: 18,
__proto__: {
address: "广州市",
},
};
console.log(obj.name, obj.age);
console.log(obj.address);
// console.log(obj.hasOwnProperty("name"));
// console.log(obj.hasOwnProperty("address"));
console.log(Object.hasOwn(obj, "name"));
console.log(Object.hasOwn(obj, "address"));
// 和 hasOwnProperty的区别
const info = Object.create(null);
info.name = "what";
// console.log(info.hasOwnProperty("name"));
console.log(Object.hasOwn(info,"name"));
ES13 - New members of classes
在ES13中,新增了定义class类中成员字段(field)的其他方式:
- Instance public fields
- Static public fields
- Instance private fields
- static private fields
- static block
class Person {
// 对象属性: public 公共 => public instance fields
height = 1.77;
// 对象属性: private 私有:程序员之间约定的
// _intro = "name is what";
// 真正的私有属性
#intro = "name is what";
// 类属性 public
static totalCount = "80亿";
// 类属性: private
static #maleTotalCount = "20亿";
constructor(name, age) {
// 对象中的属性: 在 constructor 中通过this设置
this.name = name;
this.age = age;
this.address = "广州市";
}
// 静态代码块
static {
console.log("hello world");
console.log("Hello Person");
}
}
const p = new Person("what", 17);
console.log(p);
console.log(p.name, p.age, p.height, p.address /* p.#intro */);
Q.E.D.