ECMAScript

Number

  • parseInt() 用于任何数据类型转换成数值

  • parseInt() 解析字符串,返回整数

  • parseFloat() 解析字符串,返回浮点数

  • 如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN;
    1. 可以使用内置函数 isNaN() 来判断一个变量是否为 NaN; isNaN(NaN) = true
  • 内置函数 isFinite() 用于判断一个变量是否是一个有穷数。
    1. 如果判断类型为 Infinity、-Infinity、NaN,则返回false;
    2. isFinite(“0”) => true;
    3. 如果是纯数值类型的检测,则返回false:Number.isFinite(“0”);

相关参考:parseInt/parseFloat/Number

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,那么将这一项放入新数组,返回新数组;

相关参考 数组详细操作方法及解析合集/OBKoro1

ES6

ES7新特性

  1. 求幂运算符(**)
  2. Array.prototype.includes()
  3. 函数作用域中严格模式的变更
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

More


1.5万字概括ES6全部特性

10分钟学会ES7+ES8 / 大转转FE

ECMAScript 6 入门 / 阮一峰

ECMAScript 2015 功能概述

Javascript的8张思维导图

js系列

悟透JavaScript

js 模块化开发

你不知道的JavaScript

彻底理解js中this的指向

对Js赋值运算的新认识

Front-End-Basics