之前我们可以通过Object.keys()获取对象的所有的key。
在ES8中提供了Object.values()获取对象的所有的value值。
const obj={
name:"wjy",
age:18
}
const keys=Object.keys(obj);
const values=Object.values(obj);
console.log(keys,values);
console.log(Object.values([1,2,3,4]));//如果传入的是一个数组,则返回的是数组本身
console.log(Object.values("abc"));//如果传入的是一个字符串, 将字符串中所有的字符放入到一个数组中,[ 'a', 'b', 'c' ]
通过Object.entries可以获取到一个数组,数组中会存放可枚举属性的键值对数组。([[],[]])
// * 可获取到一个数组,数组存放的是可枚举属性的键值对数组
const obj={
name:"wjy",
age:20,
}
console.log(Object.entries(obj));//[ [ 'name', 'wjy' ], [ 'age', 20 ] ]
const entries=Object.entries(obj);
entries.forEach((item)=>{
console.log(item[0],":",item[1]);
})
// * 还可以传入一个数组,会将索引值作为key,对应的值作为value
console.log(Object.entries(["wjy","hyz","tl"]));//[ [ '0', 'wjy' ], [ '1', 'hyz' ], [ '2', 'tl' ] ]
// * 如果传入一个字符串,会将索引值作为key,value为对应的字符串
console.log(Object.entries("abc"));//[ [ '0', 'a' ], [ '1', 'b' ], [ '2', 'c' ] ]
某些字符串外面需要对其进行前后的填充,来实现某种格式化效果,ES8中增加了padStart何padEnd方法,,分别是对字符串的首尾进行填充的。
const message="Hello World";
const newMessage=message.padStart(15,"*").padStart(20,0)
console.log(newMessage);
// * 案例
const cardNumber="113334789527057429";
// * 后四位前面全是*
const lastFourNum=cardNumber.slice(-4);
const finalCard=lastFourNum.padStart(cardNumber.length,"*")
console.log(finalCard);//**************7429
允许在函数定义和调用时多加一个逗号
// * 允许在函数定义和调用时多加一个逗号
function sum(a,b,){
return a+b;
}
console.log(sum(1,2,));
// * 获取一个对象的所有属性描述符
const obj={
name:"wjy",
age:20
}
console.log(Object.getOwnPropertyDescriptors(obj));
// {
// name: {
// value: 'wjy',
// writable: true,
// enumerable: true,
// configurable: true
// },
// age: { value: 20, writable: true, enumerable: true, configurable: true }
// }
flat()方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中元素合并为一个新数组返回。
flatMap()方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
// * flat的使用
const nums=[10,20,[2,9],[[30,40],[10,45]],78,[55,88]];
const newNum=nums.flat(1);
console.log(newNum);//[ 10, 20, 2, 9, [ 30, 40 ], [ 10, 45 ], 78, 55, 88 ]
const newNum2=nums.flat(2);
console.log(newNum2);
// [
// 10, 20, 2, 9, 30,
// 40, 10, 45, 78, 55,
// 88
// ]
// * flatMap
const nums2=[10,20,30];
const newNums2=nums2.flatMap((item)=>item*2);
console.log(newNums2);
// * flatMap的应用场景
const messages=["hello world","你好啊 李银河","my name is coderwhy"];
const words=messages.flatMap((item)=>item.split(" "))
console.log(words);
// [
// 'hello', 'world',
// '你好啊', '李银河',
// 'my', 'name',
// 'is', 'coderwhy'
// ]
在前面,我们可以通过Object.entries将一个对象转换成entries,那么如果我们有一个entries,如何将其转换成对象呢?
ES10提供了Object.fromEntries来完成转换。
const obj={
name:"wjy",
age:20,
height:1.6
}
const objEntries=Object.entries(obj);
// 怎么将Entries转化为之前的对象呢
// *ES10之前的用法
const newObj={};
objEntries.forEach((item)=>{
newObj[item[0]]=item[1];
})
console.log("newObj:",newObj);
// * ES10
const objEntriesToObj=Object.fromEntries(objEntries);
console.log(objEntriesToObj);
// * for...in 拿的到是数组的索引值
const queryString="name=wjy&age=18&height=1.88";
const queryParams=new URLSearchParams(queryString);
console.log(queryParams);//* URLSearchParams { 'name' => 'wjy', 'age' => '18', 'height' => '1.88' }
for(const item of queryParams){
console.log(item);//[ 'name', 'wjy' ]
}
const objParams=Object.fromEntries(queryParams);
console.log(objParams);//{ name: 'wjy', age: '18', height: '1.88' }
trimStart:去除头部空格
trimEnd:去除尾部空格
const message=" Hello World ";
//trim是ES10之前的 去除首尾空格
// trimStart:去除头部空格
// trimEnd;去除尾部空格
console.log(message.trim());//* Hello World
console.log(message.trimStart());//Hello World
console.log(message.trimEnd());// Hello World
在早期的Javascript中,我们不能正确的表示过大的数字:
如何表示一个大数呢?
在数值后面加一个n
如果一个大数与一个小数相加会报错,需要将小数也表示与大数,才能正确进行运算
如果将一个大数转化为小数,可能是不正确的,不安全的。
// * 在早期的js中,我们不能正确的表示过大的数字
// * 大于MAX_SAFE_INTEGER的数值,表示的可能是不正确的
// ES11之前 最大的数字
const maxInt=Number.MAX_SAFE_INTEGER;//9007199254740991
console.log(maxInt);
console.log(maxInt+1);//9007199254740992
console.log(maxInt+2);//9007199254740992
//* ES11 在数值后加个n
const bigInt=900719925474099100n;
// console.log(bigInt+100);//* 报错
console.log(bigInt+100n);//900719925474099200n
console.log(bigInt+BigInt(100));//900719925474099200n
const smallNum=Number(bigInt);//不一定是正确的
console.log(smallNum);
Nullish Coalescing Operator:空值合并运算 ??
// * 空值合并运算 ??
let foo;
// const bar=foo|| "default value" ;//* 逻辑或:有缺陷:0 空字符串 false 最后都会取默认值
const bar=foo??"default value";//这个只有当foo的值是null或者undefined,才会去后面运算
console.log(bar);
主要作用是让我们的代码在进行null或undefined判断时更加清晰和简洁,可以避免有些错误
语法:
?.
const info={
name:"wjy",
friend:{
name:"LiLei",
girlFriend:{
name:"hmm"
}
}
}
// 想要获取info.friend.girlFriend.name的值
// console.log(info.friend.girlFriend.name);
// * 在前端获取数据时,如果数据还未从后端获取到,再使用undefined.操作时就会报错
if(info&&info.friend&&info.friend.girlFriend){//* 所以需要这样进行判断,但是这样写似乎太长了,代码可读性差
console.log(info.friend.girlFriend.name);
}
// * ES11提供了可选链 Optional
console.log(info.friend?.girlFriend?.name);
在之前我们希望获取JavaScript环境的全局对象,不同的环境获取的方式是不一样的。
在ES11中,使用globalThis来获取全局对象,在不同环境中,指向不同的全局对象。
// * 获取某个环境的全局对象
// * 在浏览器中
// console.log(this);
// console.log(window);
// * Node环境下
// console.log(global);
// * 在不同环境下,显示不同的全局对象 globalThis
console.log(globalThis);
在ES11之前,虽然有很多浏览器支持for...in来遍历对象类型,但是并没有被ECMA标准化。
在ES11中,对其进行了标准化,for...in是用于遍历对象的key
const obj={
name:"wjy",
age:20,
height:1.88
}
for(const item in obj){
console.log(item);
}
FinalizationRegistry对象可以让你在对象被垃圾回收时请求一个回调。
以下代码建议在浏览中运行,会看到效果的。
// * FinalizationRegistry是一个类型
const finalRegistry=new FinalizationRegistry((value)=>{
console.log("注册在finalRegistry的某个对象被销毁了",value);
});
let obj={
name:"why"
}
let info={
age:18
}
finalRegistry.register(obj,"obj");
finalRegistry.register(info,"info");
obj=null;//* GC不定时来检查内存中是否有要销毁的对象
info=null;
强引用
// * FinalizationRegistry是一个类型
const finalRegistry=new FinalizationRegistry((value)=>{
console.log("注册在finalRegistry的某个对象被销毁了",value);
});
let obj={
name:"why"
}
let info=obj;
finalRegistry.register(obj,"obj");
obj=null;//* 即使obj指向null,但是obj原来指向的那片内存空间由info指向的,所以并不会被销毁
弱引用
// * FinalizationRegistry是一个类型
const finalRegistry=new FinalizationRegistry((value)=>{
console.log("注册在finalRegistry的某个对象被销毁了",value);
});
let obj={
name:"why"
}
let info=new WeakSet();
info.add(obj)
finalRegistry.register(obj,"obj");
obj=null;//* 因为obj指向null,但是obj原来指向的那片内存空间由info指向的(弱引用),所以GC最后会将obj对应的内存空间销毁的
如果我们默认将一个对象赋值给另外一个引用时,那么这个引用是一个强引用。
// * FinalizationRegistry是一个类型
const finalRegistry=new FinalizationRegistry((value)=>{
console.log("注册在finalRegistry的某个对象被销毁了",value);
});
let obj={
name:"wjy"
}
// let info=obj;
// let info=new WeakSet();
// info.add(obj)
let info=new WeakRef(obj);
console.log(info.deref().name);//why
finalRegistry.register(obj,"obj");
obj=null;//* 因为obj指向null,但是obj原来指向的那片内存空间由info指向的(弱引用),所以GC最后会将obj对应的内存空间销毁的
setTimeout(()=>{
// * info.deref() 如果被销毁了,则为undefined
console.log(info.deref()&&info.deref().name);
},10*1000)
// * || 逻辑或
let message="";
// message=message||"default value";
// * ||=
message||="default value";
console.log(message);
// * && 逻辑与
// const obj={
// name:"wjy",
// foo:function(){
// console.log("foo函数被调用了");
// }
// }
// obj.foo&&obj.foo()
// * &&=
let info={
name:"wjy"
}
// * 首先判断info是否有值,取出info.name
// info=info&&info.name;
info&&=info.name
console.log(info);//wjy
// * ?? 逻辑空运算
let message2="";
message2=message2??="default value";
console.log(message2);