字符扩展
"\u{20BB7}" //正确解读双字节字符'𠮷'
//codePointAt 正确处理4个字节储存的字符,返回一个字符的码点。
var s = '𠮷a';
for (let ch of s) {console.log(ch.codePointAt(0).toString(16));}
// 20bb7 61
//不能用for in(for in遍历的是数组的索引,而for of遍历的是数组元素值,正确识一个字符。)
String.fromCodePoint
String.fromCodePoint(0x20BB7)// "𠮷"
includes(), startsWith(), endsWith()
vars='Hello world!';
s.startsWith('Hello')// true
s.endsWith('!')// true
s.includes('o')// true
//使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。
repeat()
'x'.repeat(3)// "xxx"
'na'.repeat(0);'na'.repeat(NaN)// ""
padStart(),padEnd()
'x'.padStart(4,'ab')// 'abax'
'abc'.padStart(10,'0123456789')// '0123456abc'
'x'.padStart(4)// ' x'(空格填充)
'x'.padEnd(5,'ab')// 'xabab'
模板字符串(用反引号(`)标识,ESC下方的按键)
$('#result').append(`
There are ${basket.count} items in your basket.
`.trim());//.trim()去掉Threre前面的换行
正则
除了ig外添加了u(可识别码点大于0xFFFF的 Unicode 字符),y(粘连,从剩余的第一个位置开始)
vars='aaa_aa_a';
varr1=/a+/g;
varr2=/a+/y;
r1.exec(s)// ["aaa"]
r2.exec(s)// ["aaa"]
r1.exec(s)// ["aa"]
r2.exec(s)// null
数值
二进制和八进制分别用前缀0b(或0B)和0o(或0O)表示。
Number('0b111')// 7 转为十进制
Number.isFinite()用来检查一个数值是否为有限
parseInt()和parseFloat(),移植到Number对象上面(不再是全局)
Number.isInteger()是否为整数(3.0也是整数)
Number.EPSILON极小量(浮点数计算误差能够小于Number.EPSILON,我们就可以认为得到了正确结果)
Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER表示JavaScript能够准确表示的整数范围,Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内。
Math.trunc获取整数部分。(4.1返回4,-4.1返回-4,相当于returnx<0?Math.ceil(x):Math.floor(x);)
Math.cbrt方法用于计算一个数的立方根。
Math.hypot方法返回所有参数的平方和的平方根(Math.hypot(3,4);// 5)
Math.expm1()返回ex- 1
Math.log1p(x)方法返回1 + x的自然对数
Math.log10(x)返回以10为底的x的对数
Math.log2(x)返回以2为底的x的对数
Math.sinh(x),Math.cosh(x),Math.tanh(x),Math.asinh(x),Math.acosh(x),Math.atanh(x)
指数运算符(**)
2**3// 8
Integer对象,没有位数的限制,任何位数的整数都可以精确表示
1n+2n// 3n
Integer(123)// 123n
Integer 类型不能与 Number 类型进行混合运算。
0n==0// 报错 TypeError
rest 参数(参数搭配的变量是一个数组,该变量将多余的参数放入数组中。)
functionadd(...values)
{letsum=0;for(varval of values){sum+=val;}returnsum;}add(2,5,3)// 10
箭头函数(函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象)
varf=v=>v;
等同于:
varf=function(v){returnv;};
尾调用(函数的最后一步是调用另一个函数)
functionf(x){if(x>0){returnm(x)}returnn(x);}
数组 运算符扩展
console.log(...[1,2,3])// 1 2 3
vararr1=[0,1,2];vararr2=[3,4,5];arr1.push(...arr2);
varnodeList=document.querySelectorAll('div');vararray=[...nodeList];//转为数组
vargo=function*(){yield1;yield2;yield3;};[...go()]// [1, 2, 3](变量go是一个 Generator 函数)
Array.from()(将类似数组的对象和可遍历的对象转为真正的数组,返回一个新的数组)
letarrayLike={'0':'a','1':'b','2':'c',length:3};
letarr2=Array.from(arrayLike);// ['a', 'b', 'c']
Array.from([1,2,3],(x)=>x*x)//[1, 4, 9]类似map
copyWithin()
[1,2,3,4,5].copyWithin(0,2);// [3, 4, 5, 4, 5]
find() 和 findIndex()
[1,4,-5,10].find((n)=>n<0)// -5(用于找出第一个符合条件的数组成员)
[NaN].findIndex(y=>Object.is(NaN,y))// 0返回第一个符合条件的数组成员的位置(indexof不能识别NaN)
fill()填充数组,数组初始化
['a','b','c'].fill(7,1,2)// ['a', 7, 'c']从1号位开始,向原数组填充7,到2号位之前结束。
includes()数组是否包含给定的值
[1,2,3].includes(3,3);// false,第二个参数表示搜索的起始位置,可搜索NaN
对象
Object.is()//类似于===,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
Object.is(+0,-0)// false
Object.is(NaN,NaN)// true
Object.assign()对象的合并,浅拷贝,null和undefined不能为首参数
var target={a:1,b:1};var source1={b:2,c:2};var source2{c:3};
Object.assign(target,source1,source2);
target// {a:1, b:2, c:3}
typeofObject.assign(2)// "object"
Object.assign([1,2,3],[4,5])// [4, 5, 3]
getOwnPropertyDescriptors()返回指定对象所有自身属性(非继承属性)的描述对象。
Object.setPrototypeOf()设置一个对象的prototype对象,返回参数对象本身(如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。)
let proto={};let obj={x:10};
Object.setPrototypeOf(obj,proto);
proto.y=20;
obj.x// 10
obj.y// 20
Object.getPrototypeOf()读取一个对象的原型对象。
Null 传导运算符
message?.body?.user?.firstName||'default'相当于
(message&&message.body&&message.body.user&&message.body.user.firstName)||'default'
Symbol表示独一无二的值,它是 JavaScript 语言的第七种数据类型,不能运算,可以转为布尔值和string
vars1=Symbol('foo');//函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述
s1// Symbol(foo) s1.toString()// "Symbol(foo)"
var myS=Symbol();
var a={}; a[myS]='Hello!';//Symbol 值作为对象属性名时,不能用点运算符,要用[]
Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名(数组)。(for...in、for...of,Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()中无返回)
let obj={
[Symbol('my_key')]:1,
enum:2,nonEnum:3};
Reflect.ownKeys(obj)// ["enum", "nonEnum", Symbol(my_key)]
我们可以利用Symbol为对象定义一些非私有的、但又希望只用于内部的方法。
var s1=Symbol.for('foo');//使用同一个Symbol值(是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。)
var s2=Symbol.for('foo');//两个都要用Symbol.for
s1===s2// true
var s1=Symbol.for("foo");
Symbol.keyFor(s1)// "foo"(已登记的 Symbol 类型值的key。)
Set(类似于数组,但是成员的值都是唯一的)
const s=new Set();[2,3,5,4,5,2,2].forEach(x=>s.add(x));
constset=newSet([...document.querySelectorAll('div')]);
[...newSet(array)]// 去除数组的重复成员,不会发生类型转换,所以5和"5"是两个不同的值(find)
let set=new Set();set.add({});set.add({});set.size// 2(两个对象总是不相等的。)
add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
let a=new Set([1,2,3]);
let b=new Set([4,3,2]);
let union=newSet([...a,...b]);// Set {1, 2, 3, 4}并集
let intersect=newSet([...a].filter(x=>b.has(x)));// set {2, 3}交集
let difference=newSet([...a].filter(x=>!b.has(x)));// Set {1}差集
WeakSet(类似set,成员只能是对象,适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失)
WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。
WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失。WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏。
map(键值对的集合,“键”的范围不限于字符串,各种类型的值)
const map=new Map();map.set(['a'],555);//可用链式写法
map.get(['a'])// undefined(内存地址是不一样的,因此get方法无法读取该键)
Map 的遍历顺序就是插入顺序。
WeakMap(只接受对象作为键名(null除外))
WeakMap 应用的典型场合就是 DOM 节点作为键名
let myElement=document.getElementById('logo');
let myWeakmap=new WeakMap();
myWeakmap.set(myElement,{timesClicked:0});
myElement.addEventListener('click',function(){letlogoData=myWeakmap.get(myElement);
logoData.timesClicked++;},false);//一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。
Proxy