No more than code.
ECMAScript
Number
-
parseInt() 用于任何数据类型转换成数值
-
parseInt() 解析字符串,返回整数
-
parseFloat() 解析字符串,返回浮点数
- 如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN;
- 可以使用内置函数 isNaN() 来判断一个变量是否为 NaN;
isNaN(NaN) = true
- 可以使用内置函数 isNaN() 来判断一个变量是否为 NaN;
- 内置函数
isFinite()
用于判断一个变量是否是一个有穷数。- 如果判断类型为 Infinity、-Infinity、NaN,则返回false;
- isFinite(“0”) => true;
- 如果是纯数值类型的检测,则返回false:Number.isFinite(“0”);
Math
Math.random()
———返回0-1之间的随机数
Math.max(num1, num2)
———返回较大的数 (若num2>num1,输出num2)
Math.min(num1, num2)
———返回较小的数
Math.abs(num)
———绝对值
Math.round(3.6)
———四舍五入
Math.ceil(11.3)
——— 向上取整 =>12
Math.floor(11.8)
———向下取整 =>11
Math.trunc(213.23)
———整数部分 =>213
Math.PI
———π
Math.sqrt()
———正平方根,如果参数是负值,返回NaN
Math.sign(x)
———返回x的符号(1,-1,0),表示x是否为正,负或零
Math.log10(x)
———返回一个数字的以10对数
Math.log2(x)
———返回一个数字的以2的对数
Math.pow(x,y)
———x的y次幂
Date
获取日期
d.getFullYear()
———获取当前年份
d.getMonth()
———获取当前月份(当前的月份从0开始)
d.getDate()
———获取当前日期
d.getDay()
———周几
d.getHours()
———时
d.getMinutes()
———分
d.getSeconds()
———秒
d.getTime()
———获取1970年到当前时间的毫秒数;【返回值每秒都在改变】
设置日期
d.setFullYear(2012)
———返回1970年1月1日到设定时间毫秒数
d.setMonth(9)
———到当前年份指定月份的毫秒数[设置4,显示5月]
d.setDate()
———到当前年份当前月份的指定日期的毫秒数
d.setHours()
d.setMinutes()
d.setSeconds()
d.setTime()
———指定时间(毫秒数) 【console.log(d.setTime(n)) => n】
设置日期返回值:从1970年1月1日到设定时间毫秒数;
Date.parse(“2015-08-24”);获取1970年到设定时间的毫秒数;
String
查询
indexOf("abc")
———查找字符串第一次出现的位置
lastIndexOf("abc")
———查找字符串最后一次出现的位置,如果没找到返回-1
replace()
———替换字符串 (返回修改后的字符串不对原字符串进行操作)
获取
charAt(3)
———获取下标为3的字符 (返回对应字符串)
charCodeAt(3)
———获取下标为3的字符的Unicode码
String.fromCharCode(94)
———编码转换成字符,适用于各种字符(英文、中文、标点等)
substring(start,end)
———截取字符串;参数(开头下标,结尾下标);注意结尾字符不截取
split(separator, howmany)
———根据分隔符、拆分成数组;可以只写一个参数
separator (字符串!!! 不是下标) :拆分位置(此位置上的项删除);
howmany:拆分后保留的项数(返回的数组的最大长度);若此数大于项数,保留原数组;
返回值=> 数组;
不加参数返回原数组;
如果空字符串(““)用作separator,那么stringObject中的每个字符之间都会被分割。
拼接
concat()
———连接字符串 (更适用于数组)
大小写
toLowerCase()
———全转小写
toUpperCase()
———全转大写
数组
a.push(item)
———数组后插入item,返回数组新长度
a.unshift(item)
———数组前插入item,返回数组新长度
a.pop()
———数组后删除元素;删除并返回数组中最后一个元素
a.shift()
———数组前删除元素;删除并返回数组中第一个元素
a.slice(start, end)
———返回子数组,以 a[start] 开头,以 a[end] 前一个元素结尾
a.splice(start, num, new)
———从 start 开始,删除num个元素,然后插入所有的new
a.sort()
———排序
a.concat()
———合并数组
a.reverse()
———数组逆序(会更改原数组)
a.join(sep)
———返回包含数组中所有元素的字符串,每个元素通过指定的 sep 分隔
a.toString()
———返回包含数组中所有元素的字符串,元素间逗号分隔
a.toLocaleString()
———返回包含数组中所有元素的字符串,元素间逗号分隔
toString()和toLocaleString()区别:
---四位数及以上 var a=1234;
a.toString() // "1234"
a.toLocaleString() // "1,234"
---日期格式 var sd=new Date();
sd.toLocaleString() // "2017/2/15 上午11:21:31"
sd.toString() // "Wed Feb 15 2017 11:21:31 GMT+0800 (CST)"
ES5新增
a.indexOf(data,start)
———返回当前数组中是否有某个数;若有返回下标,若无返回-1;
a.forEach()
———遍历;参数:(value,index,arr)=>{}
a.map()
———对数组每一项进行操作;返回值是一个操作之后的新数组,不改变原数组;
a.filter()
———判断函数返回值;若为true,那么将这一项放入新数组,返回新数组;
ES6
ES7新特性
- 求幂运算符(**)
- Array.prototype.includes()
- 函数作用域中严格模式的变更
Array.prototype.includes()
用法同indexOf();indexOf返回下标,includes返回true/false;
['a', 'b', 'c'].includes('a') // true
['a', 'b', 'c'].indexOf('a') // 0
// 注意NaN情况:
let arr = [1, NaN, 2, 3];
arr.indexOf(NaN) // -1
arr.includes(NaN) // true
求幂运算符(**)
基本用法:3 ** 2 ———9 效果同:Math.pow(3, 2) ———9
ES8新特性
异步函数(Async functions)
异步函数声明:async function foo() {};
异步函数表达式:const foo = async function () {};
异步函数定义:let obj = { async foo() {} };
异步箭头函数:const foo = async () => {};
function fetchTextByPromise() {
return new Promise(resolve => {
setTimeout(() => {
resolve("es8");
}, 2000);
});
}
async function sayHello() {
const externalFetchedText = await fetchTextByPromise();
console.log(`Hello, ${externalFetchedText}`); // Hello, es8
}
sayHello();
console.log(1);
sayHello();
console.log(2);
// 调用结果
1 // immediately
2 // immediately
Hello, es8 // after 2 seconds
常见用法汇总:
//1. 处理单个异步结果
async function asyncFunc() {
const result = await otherAsyncFunc();
console.log(result);
}
//2. 顺序处理多个异步结果
async function asyncFunc() {
const result1 = await otherAsyncFunc1();
console.log(result1);
const result2 = await otherAsyncFunc2();
console.log(result2);
}
//3. 并行处理多个异步结果
async function asyncFunc() {
const [result1, result2] = await Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2()
]);
console.log(result1, result2);
}
//4. 处理错误
async function asyncFunc() {
try {
await otherAsyncFunc();
} catch (err) {
console.error(err);
}
}
相关参考:一次性让你懂async/await
Object.entries() & Object.values()
Object.entries()
如果一个对象是具有键值对的数据结构,则每一个键值对都将会编译成一个具有两个元素的数组,这些数组最终会放到一个数组中,返回一个二维数组。简言之,该方法会将某个对象的可枚举属性与值按照二维数组的方式返回。若目标对象是数组时,则会将数组的下标作为键值返回。
Object.entries({ one: 1, two: 2 }) => [['one', 1], ['two', 2]]
Object.entries([1, 2]) => [['0', 1], ['1', 2]]
//注意:键值对中,如果键的值是Symbol,编译时将会被忽略:
Object.entries({ [Symbol()]: 1, two: 2 }) => [['two', 2]]
//Object.entries()返回的数组的顺序与for-in循环保持一致,
//即如果对象的key值是数字,则返回值会对key值进行排序,返回的是排序后的结果:
Object.entries({ 3: 'a', 4: 'b', 1: 'c' }) => [['1', 'c'], ['3', 'a'], ['4', 'b']]
//使用Object.entries(),我们还可以进行对象属性的遍历:
let obj = { one: 1, two: 2 };
for (let [k,v] of Object.entries(obj)) {
console.log(`${JSON.stringify(k)}: ${JSON.stringify(v)}`);
}
//输出结果如下:
'one': 1
'two': 2
Object.values()
返回自己的键值对中属性的值。它返回的数组顺序,跟Object.entries()保持一致。
Object.values({ one: 1, two: 2 }) // [1, 2]
Object.values({ 3: 'a', 4: 'b', 1: 'c' }) // ['c', 'a', 'b']
字符串填充
padStart
函数通过填充字符串的首部来保证字符串达到固定的长度;
padEnd
是填充字符串的尾部来保证字符串的长度的;
//两个参数:字符串目标长度和填充字段,其中第二个参数可以不填,默认情况下使用空格填充
'Vue'.padStart(10) //' Vue'
'React'.padStart(10) //' React'
'JavaScript'.padStart(10) //'JavaScript'
//可以看出,多个数据如果都采用同样长度的padStart,相当于将呈现内容右对齐。
//可以指定字符串来代替空字符串:
'Vue'.padStart(10, '_*') //'_*_*_*_Vue'
'React'.padStart(10, 'Hello') //'HelloReact'
'JavaScript'.padStart(10, 'Hi') //'JavaScript'
'JavaScript'.padStart(8, 'Hi') //'JavaScript'
//从上面结果来看,填充函数只有在字符长度小于目标长度时才有效;
//若字符长度已经等于或小于目标长度时,填充字符不会起作用;
//目标长度如果小于字符串本身长度时,字符串也不会做截断处理,只会原样输出
//padEnd函数作用同padStart,只不过它是从字符串尾部做填充:
'Vue'.padEnd(10, '_*') //'Vue_*_*_*_'
'React'.padEnd(10, 'Hello') //'ReactHello'
'JavaScript'.padEnd(10, 'Hi') //'JavaScript'
'JavaScript'.padEnd(8, 'Hi') //'JavaScript'
Object.getOwnPropertyDescriptors()
该方法会返回目标对象中所有属性的属性描述符,该属性必须是对象自己定义的,不能是从原型链继承来的。
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
},
set grade(g) {
console.log(g)
}
}
Object.getOwnPropertyDescriptors(obj)
//输出结果为:
{
gender: {
configurable: true,
enumerable: true,
get: f gender(),
set: undefined
},
grade: {
configurable: true,
enumerable: true,
get: undefined,
set: f grade(g)
},
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
name: {
configurable: true,
enumerable: true,
value: 'test',
writable: true
}
}
//方法还提供了第二个参数,用来获取指定属性的属性描述符。
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
},
set grade(g) {
console.log(g)
}
}
Object.getOwnPropertyDescriptors(obj, 'id')
//输出结果为:
{
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
}
}
由上述例子可知,该方法返回的描述符,会有两种类型:数据描述符、存取器描述符。返回结果中包含的键可能的值有:configurable、enumerable、value、writable、get、set。
使用过Object.assign()的同学都知道,assign方法只能拷贝一个属性的值,而不会拷贝它背后的复制方法和取值方法。Object.getOwnPropertyDescriptors()主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
}
}
Object.assign(obj)
//输出结果为:
{
gender: undefined
id: 1,
name: 'test'
}
//Object.getOwnPropertyDescriptors方法配合Object.defineProperties方法,就可以实现正确拷贝。
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
}
}
let obj1 = {}
Object.defineProperties(obj1, Object.getOwnPropertyDescriptors(obj))
Object.getOwnPropertyDescriptors(obj1)
//输出结果为:
{
gender: {
configurable: true,
enumerable: true,
get: f gender(),
set: undefined
},
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
name: {
configurable: true,
enumerable: true,
value: 'test',
writable: true
}
}
更多Object.getOwnPropertyDescriptors的使用细则,可参见阮一峰的博客文章
共享内存和原子(Shared memory and atomics)
共享内存允许多个线程并发读写数据,而原子操作则能够进行并发控制,确保多个存在竞争关系的线程顺序执行。本部分则介绍了新的构造器 SharedArrayBuffer 与包含静态方法的命名空间对象 Atomics。Atomic 对象类似于 Math,我们无法直接创建其实例,而只能使用其提供的静态方法:
add /sub - 增加或者减去某个位置的某个值
and / or /xor - 进行位操作
load - 获取值
函数参数列表与调用中的尾部逗号
该特性允许我们在定义或者调用函数时添加尾部逗号而不报错。
let foo = function (a,b,c,) {
console.log('a:', a)
console.log('b:', b)
console.log('c:', c)
}
foo(1, 3, 4, )
//输出结果为:
a: 1
b: 3
c: 4
ES9新特性
Rest(剩余)/Spread(展开) 属性
ES6 在处理数组解构时,引入了 rest(剩余)元素的概念,ES2018 为对象引入了类似的功能。
// ES6-rest
const nums = [1,2,3,4,5];
[first,second,...others] = nums;
// ES6-spread
const nums = [1,2,3,4,5];
const sum = (a,b,c,d,e) => a+b+c+d+e;
const sum = sum(..nums);
// ES9-rest
const {first,second,...others} = {first:1,second:2,third:3,fourth:4,fifth:5}
// first: 1;
// second: 2;
// others: {third:3,fourth:4,fifth:5}
// ES9-spread
const items = {first,second,...others};
// items: {first:1,second:2,third:3,fourth:4,fifth:5}
Asynchronous iteration (异步迭代)
for-await-of
for await (const line of readLines(filePath)) {
console.log(line)
}
Promise.prototype.finally()
当一个 promise 得到满足(fulfilled)时,它会一个接一个地调用 then() 方法。 如果在此期间发生错误,则跳过 then() 方法并执行 catch()方法。 finally() 允许您运行一些代码,无论 promise 的执行成功或失败:
fetch('file.json')
.then(data => data.json())
.catch(error => console.error(error))
.finally(() => console.log('finished'))
正则表达改进:先行断言(lookahead) 和 后行断言(lookbehind)
正则表达式后行断言(lookbehind):根据前面的内容匹配字符串。 ?< =
下面是一个先行断言(lookahead):您可以使用 ?= 匹配一个字符串,该字符串后面跟着一个特定的子字符串:
/Roger(?=Waters)/
/Roger(?= Waters)/.test('Roger is my dog') //false
/Roger(?= Waters)/.test('Roger is my dog and Roger Waters is a famous musician') //true
?! 执行逆操作,匹配一个字符串,该字符串后面没有一个特定的子字符串:
/Roger(?!Waters)/
/Roger(?! Waters)/.test('Roger is my dog') //true
/Roger(?! Waters)/.test('Roger Waters is a famous musician') //false
后行断言:?< =
/(?<=Roger) Waters/
/(?<=Roger) Waters/.test('Pink Waters is my dog') //false
/(?<=Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //true
后行断言(lookbehind) 逆操作,使用 ?< !。
/(?<!Roger) Waters/
/(?<!Roger) Waters/.test('Pink Waters is my dog') //true
/(?<!Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //false
Unicode 属性转义 \p{…} 和 \P{…}
\p{} 匹配所有 Unicode 字符,否定为 \P{}
任何 unicode 字符都有一组属性。 例如,Script 确定语言系列,ASCII 是一个布尔值, 对于 ASCII 字符,值为 true,依此类推。 您可以将此属性放在花括号中,正则表达式将检查是否为真:
/^\p{ASCII}+$/u.test('abc') //✅
/^\p{ASCII}+$/u.test('ABC@') //✅
/^\p{ASCII}+$/u.test('ABC🙃') //❌
ASCII_Hex_Digit 是另一个布尔属性,用于检查字符串是否仅包含有效的十六进制数字:
/^\p{ASCII_Hex_Digit}+$/u.test('0123456789ABCDEF') //✅
/^\p{ASCII_Hex_Digit}+$/u.test('h') //❌
还有许多其他布尔属性,您只需通过在花括号中添加它们的名称来检查它们,包括 Uppercase, Lowercase, White_Space, Alphabetic, Emoji 等:
/^\p{Lowercase}$/u.test('h') //✅
/^\p{Uppercase}$/u.test('H') //✅
/^\p{Emoji}+$/u.test('H') //❌
/^\p{Emoji}+$/u.test('🙃🙃') //✅
除了这些二进制属性之外,您还可以检查任何 unicode 字符属性以匹配特定值。在这个例子中,我检查字符串是用希腊语还是拉丁字母写的:
/^\p{Script=Greek}+$/u.test('ελληνικ?') //✅
/^\p{Script=Latin}+$/u.test('hey') //✅
ES10新特性
BigInt - 任意精度整数
BigInt 是第 7 种原始类型。
BigInt 是一个任意精度的整数。这意味着变量现在可以代表2^53个数字。而且最大限度是 9007199254740992。
const b = 1n; // 追加n来创建一个BigInt
在过去的整数值大于 9007199254740992 不支持。如果超出,则该值将锁定为 MAX_SAFE_INTEGER + 1:
const limit = Number.MAX_SAFE_INTEGER;
⇨ 9007199254740991
limit + 1;
⇨ 9007199254740992
limit + 2;
⇨ 9007199254740992 <--- MAX_SAFE_INTEGER + 1 exceeded
const larger = 9007199254740991n;
⇨9007199254740991n
const integer = BigInt(9007199254740991);
⇨9007199254740991n
const same = BigInt("9007199254740991");
⇨9007199254740991n
typeof 10; ⇨ 'number'
typeof 10n; ⇨ 'bigint'
10n === BigInt(10); ⇨ true
10n==10; ⇨true
200n / 10n ⇨ 20n
200n / 20 ⇨ Uncaught TypeError:Cannot mix BigInt and other types, use explicit conversions <
-100n ⇨ -100n
+100n ⇨ Uncaught TypeError:Cannot convert a BigInt value to a number
string.prototype.matchAll()
import - 动态导入分配给一个变量
element.addEventListener("click",async()=>{
const module = await import("./api/click.js");
module.clickEvent();
})
Array.flat() - 扁平化多维数组
let multi = [1,2,3,[4,5,6,[7,8,9[10,11,12]]]]
multi.flat(); // [1,2,3,4,5,6,Arrat(4)]
multi.flat().flat(); // [1,2,3,4,5,6,7,8,9,Arrat(3)]
multi.flat().flat().flat(); // [1,2,3,4,5,6,7,8,9,10,11,12]
multi.flat(Infinity); // [1,2,3,4,5,6,7,8,9,10,11,12]
Object.fromEntries()
String.trimStart() & String.trimEnd()
var greeting = " hello ";
greeting.trimStart(); // "hello "
greeting.trimEnd(); // " hello"
格式良好的JSON.stringify()
U + 2028和U + 2029字符
稳定的 Array.prototype.sort()
var fruit = [
{ name:"apple", count: 13 },
{ name:"orange", count: 12 },
{ name:"pear", count: 11 },
{ name:"banana", count: 11 },
{ name:"cherry", count: 12 },
{ name:"pineapple", count: 10 },
];
var my_sort = (a,b)=>a.count-b.count;
var fruitSorted = fruit.sort(my_sort);
console.log(fruitSorted);
[
{name: "pineapple", count: 10}
{name: "pear", count: 11}
{name: "banana", count: 11}
{name: "orange", count: 12}
{name: "cherry", count: 12}
{name: "apple", count: 13}
]
New Function.toString()
console.log(function fn(params) { console.log(111); }.toString());
// function fn(params) { console.log(111); }
标准化的 globalThis 对象
ES11新特性
String.prototype.matchAll
match() 方法仅返回完整的匹配结果; matchAll() 返回完整的匹配结果及特定正则表达式组(Regex groups)的信息
const text = "From 2019.01.29 to 2019.01.30";
const regexp = /(?<year>\d{4}).(?<month>\d{2}).(?<day>\d{2})/gu;
const results = text.match(regexp);
console.log(results);
// [ '2019.01.29', '2019.01.30' ]
const text = "From 2019.01.29 to 2019.01.30";
const regexp = /(?<year>\d{4}).(?<month>\d{2}).(?<day>\d{2})/gu;
const results = Array.from(text.matchAll(regexp));
console.log(results);
// [
// [
// '2019.01.29',
// '2019',
// '01',
// '29',
// index: 5,
// input: 'From 2019.01.29 to 2019.01.30',
// groups: [Object: null prototype] { year: '2019', month: '01', day: '29' }
// ],
// [
// '2019.01.30',
// '2019',
// '01',
// '30',
// index: 19,
// input: 'From 2019.01.29 to 2019.01.30',
// groups: [Object: null prototype] { year: '2019', month: '01', day: '30' }
// ]
// ]
import()
import() 返回了一个强大的 promise 函数 提示:请不要滥用动态导入(只有在必要情况下采用)。静态框架能更好的初始化依赖,而且更有利于静态分析工具和 tree shaking 发挥作用。 @babel/preset-env 已经包含了 @babel/plugin-syntax-dynamic-import ,因此如果要使用 import 语法,只需要配置 @babel/preset-env 即可。
const modulePage = 'page.js';
import(modulePage).then((module) => { module.default(); });
// or
(async () => {
const helpersModule = 'helpers.js';
const module = await import(helpersModule)
const total = module.sum(2, 2);
})();
BigInt – 任意精度整数
BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。为了和 Number 类型进行区分, BigInt 类型的数据必须添加后缀 n .
Number 类型在超过9009199254740991后,计算结果即出现问题。 Number 类型不能表示大于 2 的 1024 次方的数值 BigInt 类型可以表示任意位数的整数
BigInt 和 Number 是两种数据类型,不能直接进行四则运算,不过可以进行比较操作。
console.log( 99n == 99); //true
console.log( 99n === 99); //false
globalThis
ES2020 中引入 globalThis 作为顶层对象,在任何环境下,都可以简单的通过 globalThis 拿到顶层对象。
Promise.allSettled
可以用在处理所有的 promise 都 settled 的情况,无论结果是 fulfilled 还是 rejected. 你看 ,无需 catch!
Promise.allSettled([
fetch("https://api.github.com/users/pawelgrzybek").then(data => data.json()),
fetch("https://api.github.com/users/danjordan").then(data => data.json())
])
.then(result => console.log(`All profile settled`));
export * as ns from “mod”
import.meta
可选链
// 之前
const title = data && data.article && data.article.title
// 之后
const title = data?.article?.title
空值合并运算符
与 | 相比,空值合并运算符 ?? 只会在左边的值严格等于 null 或 undefined 时起作用。 |
"" || "default value"
// default value
"" ?? "default value"
// ""
null ?? "default value"
// default value
undefined ?? "default value"
// default value