ES6, ES7, ES8, ES9 以及 ES10 新特征

目录

1.  ES6 新特征 (2015)

1.1 module

1.1.1 export

1.1.2 import

1.2 Arrow function (箭头函数)

1.2.1 箭头函数结构

1.3 默认参数

1.4 模板字符串

1.5. 解构赋值

1.5.1数组的结构赋值

1.5.2 对象解构赋值

1.6 扩展运算符

1.7Promise(异步)

2 ES7新特征 (2016)

2.1 includes()

2.2 index operator** (指数运算符 **)

3  es8 新特征(2017)

3.1 async/await 

3.2 Object.keys()

3.3 Object.values()

3.4 Object.entries()

3.5 字符串填充

3.6 Object.getOwnPropertyDescriptors()

3.7 SharedArrayBuffer对象

3.8 原子对象

4 ES9新特征 (2018)

4.1 asynchronous iterator (异步迭代器)

4.2 非转义序列的模板字符串

4.3 正则表达式反向断言

4.4 正则表达式Unicode转义

4.5 正则表达式s/dotAll模式

4.6 正则表达式命名捕获组

4.7 object expansion operator

4.8 Promise.finally()

5  ES10 新特征 (2019)

5.1 添加Array的flat()方法和flatMap()方法

5.1.1 flat()

5.1.2 flatMap()

5.2 增加了String的trimStart()方法和trimEnd()方法

5.3 Object.fromEntries()

5.4 Symbol.prototype.description

5.5 String.protype.matchAll()

5.6 Function.prototype.toString()现在返回精确的字符,包括空格和注释

5.7 JSON⊂ECMAScript

5.8 简化try {} catch{}并修改catch绑定

5.9 新的基本数据类型BigInt


1.  ES6 新特征 (2015)

  • class (类)
  • Modularization (模块化)
  • Arrow function (箭头函数)
  • Function parameter defaults (函数参数的默认值)
  • Template string (模板字符串)
  • Destructuring assignment  (结构赋值)
  • Extension operator (扩展运算符)
  • Object attribute shorthand (对象属性简写)
  • Promise  
  • Let and Const

1.1 module

ES5不支持本机模块化,添加模块是ES6的重要组成部分。模块的功能主要由导出和导入两部分组成。每个模块都有自己的作用域。模块之间的相互调用关系是通过导出指定模块暴露的接口,通过导入引用其他模块提供的接口。同时,它还为模块创建命名空间,以防止函数命名冲突。

1.1.1 export


//导出变量
export var name = 'Rainbow'
 
var name = 'Rainbow';
var age = '24';
export {name, age};
 
 
//导出常数
export const sqrt = Math.sqrt;
 
//导出函数
export function myModule(someArg) {
  return someArg;

1.1.2 import

import {myModule} from 'myModule';//使用解构赋值
import {name,age} from 'test';
 
//import语句可以同时导入默认函数和其他变量。
import defaultMethod, { otherMethod } from 'xxx.js';

1.2 Arrow function (箭头函数)

这是ES6最令人兴奋的特性之一。它不仅仅是关键字function的缩写,它还带来了其他好处。箭头函数与周围的代码共享相同的this,可以帮助您解决这个指向的问题。有经验的JavaScript开发人员熟悉var self = this;或者var that = this指向周边this。但是如果使用= >,则不需要这种模式。

1.2.1 箭头函数结构

箭头函数的箭头= >前面是一个空括号,一个参数名,或括号内括的多个参数名,箭头后面可以是一个表达式(作为函数的返回值),或花括号内括的函数体(需要自己返回值,否则为undefined)。

// 箭头函数例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0){
        return 0;
    }
    return 1000/e;


无论它是一个箭头函数还是一个绑定函数,它都会在每次执行时返回一个新的函数引用,所以如果你需要一个函数引用来做其他事情(比如卸载监听器),你必须自己保存这个引用

//错误例子
class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}
 
//正确例子
class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change', this._onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this._onAppPaused);
    }
    onAppPaused(event){
    }
}
 
//简化的正确方法
class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused);
    }
    onAppPaused = (event) => {
        //Define the function directly as an arrow function attribute, and bind this pointer when initializing
    }
}
 
 
//需要注意的是,无论bind函数还是arrow函数,每次都会返回一个新的函数引用,
//因此,如果你需要一个函数引用来做其他事情(比如卸载监听器),你必须自己保存这个引用。

1.3 默认参数

const test = (a='a',b='b',c='c')=>{
    return a+b+c
}
 
console.log(test('A','B','C')) //ABC
console.log(test('A','B'))     //ABc
console.log(test('A'))         //Abc

1.4 模板字符串


 
//Use template string:
 
var name = `Your name is ${first} ${last}.`

1.5. 解构赋值

1.5.1数组的结构赋值


var foo = ["one", "two", "three", "four"];
 
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
 
//如果你想忽略一些值,你可以得到你想要的值如下所示
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"
 
//你可以这样写
var a, b; //首先声明一个变量
 
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

使用结构赋值来交换两个变量的值

var a = 1;
var b = 3;
 
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

1.5.2 对象解构赋值

const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};
 
const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"

1.6 扩展运算符

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 将arr2中的所有元素追加到arr1之后并返回
//等同于
var arr4 = arr1.concat(arr2);
 
 
 
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
 
var clonedObj = { ...obj1 };
// 克隆对象: {foo: 'bar', X: 42}
 
var mergedObj = { ...obj1, ...obj2 };
//合并对象: {foo: 'Baz', X: 42, Y: 13}

在react中的应用

const params = {
    name: 'Jine',
    age: 21
}
<CustomComponent {...params} />
 
 
var params = {
    name: '123',
    title: '456',
    type: 'aaa'
}
 
var { type, ...other } = params;
 
<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />

1.7Promise(异步)


var test = (a,b)=>{
    return new Promise((reslove,reject)=>{
        //Asynchronous operation
        //...
        
        reslove(resoult)//Return correct results
        
        //...
        reject(err)    //Results on error
    })
}
 
 
//Use
 
test(a,b).then(res=>{
    //... promise reslove() 返回正确的结果并在这里执行
}).catch(err=>{
    //在前面的拒绝(错误)之后,代码将执行成
})
 
//perhaps
 
try{
    var resoult = await test(a,b)
    //...
}catch(er){
    //...
}

2 ES7新特征 (2016)

  • array includes()方法用于确定数组是否包含指定的值。如果是,则返回true,否则返回false
  • a ** b 指数运算符 等同于 Math.pow(a, b).

    2.1 includes()

includes()函数用于确定数组是否包含指定的值。如果是,则返回true。否则,它返回false

let arr = ['react', 'angular', 'vue'];
 
if (arr.includes('react'))
{
    console.log('react existence');
}

2.2 index operator** (指数运算符 **)

在ES7中,引入了指数算符,其结果等价于Math.pow(..)

console.log(2**10);// Output 1024
console.log(Math.pow(2, 10)) // Output 1024

3  es8 新特征(2017)

  • async/await
  • Object.values()
  • Object.entries()
  • 字符串填充: padStart() and padEnd(), 填充字符串达到当前长度
  • 允许在函数参数列表的末尾使用逗号
  • Object.getOwnPropertyDescriptors()
  • ShareArrayBuffer和Atomics对象,用于从共享内存位置进行读写s

    3.1 async/await 

  async function init() {
    console.log('start')
    await this.testSync()
    console.log('End')
  }
  this.init()
  async function testSync() {
    const response = await new Promise(resolve => {
      setTimeout(() => {
          resolve("async await test...");
        }, 1000);
    });
    console.log(response);
  }

3.2 Object.keys()

var obj = { foo: "bar", baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

3.3 Object.values()

var obj = { foo: "bar", baz: 42 };
Object.values(obj)
// ["bar", 42]

3.4 Object.entries()

 Object.entries 方法返回参数对象本身的所有可枚举属性(不包括继承)的键值对数组。

var obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]


const obj1 = {a: 1, b: 2, c: 3}
for(let [key,value] of Object.entries(obj1)){
    console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3

 Object.entries 方法把一个对象变成一个真正的Map结构。

var obj = { foo: 'bar', baz: 42 };
var map = new Map(Object.entries(obj));
map // Map { foo: "bar", baz: 42 }

Object object keys(), values() entries()

3.5 字符串填充

String.padStart(targetLength,[padString])

String.padEnd(targetLength,padString])

  • targetLength:当前字符串需要填充到的目标长度。如果该值小于当前字符串的长度,则返回当前字符串本身。
  • padString:(可选)填充字符串。如果字符串太长,以致填充字符串的长度超过目标长度,则只保留最左边的部分,其余部分将被截断。该参数的默认值是' '。

console.log('0.0'.padStart(4,'*'))
console.log('0.0'.padStart(20))
console.log('0.0'.padEnd(4,'*')) 
console.log('0.0'.padEnd(10,'*'))
 
/*
*0.0
                 0.0
0.0*
0.0*******
*/

3.6 Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptor 方法返回一个对象(描述符)。ES6引入了Object。方法,该方法返回指定对象的所有自身属性(非继承属性)的描述对象。

const obj = {
  foo: 123,
  get bar() { return 'abc' }
};
 
Object.getOwnPropertyDescriptors(obj)
// { foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } }

在上面的代码中,对象。方法返回一个对象。所有原始对象的属性名称就是对象的属性名称,对应的属性值就是属性描述对象。
该方法的主要目的是解决Object.assign()不能正确复制获取和设置属性的问题。

const source = {
  set foo(value) {
    console.log(value);
  }
};
 
const target1 = {};
Object.assign(target1, source);
 
Object.getOwnPropertyDescriptor(target1, 'foo')
// { value: undefined,
//   writable: true,
//   enumerable: true,
//   configurable: true }

在上面的代码中,源对象的foo属性值是一个赋值函数。对象。Assign方法将此属性复制到target1对象。因此,该属性的值没有定义。这是因为对象。赋值方法总是复制属性的值,而不是属性后面的赋值方法或值方法。
ES6 object extension - Object.getOwnPropertyDescriptors()

3.7 SharedArrayBuffer对象

使用SharedArrayBuffer,多个web工作者可以同时读写同一块内存。您不再需要延迟的postMessage通信。多个web工作者在访问数据时没有延迟
SharedArrayBuffer对象用于表示一个通用的、固定长度的原始二进制数据缓冲区,类似于ArrayBuffer对象,它可以用于在共享内存上创建视图。与ArrayBuffer不同,SharedArrayBuffer不能被分离。

/**
 * 
 * @param {*} length创建的数组缓冲区的大小,以字节为单位。  
 * @returns {SharedArrayBuffer} 指定大小的新SharedArrayBuffer对象。它的内容被初始化为0
 */
new SharedArrayBuffer(length)

Illustration of ArrayBuffers and shared ArrayBuffers

3.8 原子对象

Atomics对象提供了一组静态方法,用于对SharedArrayBuffer对象进行原子操作。

这些原子操作属于Atomics模块。与一般全局对象不同,Atomics不是构造函数,因此不能用new操作符调用它,也不能直接作为函数调用它。Atomics的所有属性和方法都是静态的(像Math对象一样)。

共享内存的多个线程可以同时在同一位置读和写数据。原子操作确保正在读或写的数据的值满足预期,即下一个原子操作直到前一个原子操作结束才开始,其操作过程不会中断。

Atomics.add()
//将指定位置的数组元素添加到给定值,并返回添加该元素之前的值。
 
 
Atomics.and()
//将指定位置的数组元素与给定值进行比较,并返回操作前元素的值。
 
Atomics.compareExchange()
//如果数组中指定的元素等于给定值,则更新为新值并返回元素的原始值。
 
 
Atomics.exchange()
//将数组中指定的元素更新为给定值,并在更新元素之前返回该值。
 
 
Atomics.load()
//返回数组中指定元素的值
 
 
Atomics.or()
//将指定位置的数组元素与给定值进行比较,并返回or操作之前元素的值。
 
 
Atomics.store()
//将数组中指定的元素设置为给定值并返回该值。
 
 
Atomics.sub()
//从给定值中减去指定位置上的数组元素,并返回减法前的元素值。
 
 
Atomics.xor()
//指定位置的数组元素与给定值或不同,并且返回排他或操作之前的元素的值。
 
// wait()和wake()方法使用Linux上的futexes模型(快速用户空间互斥锁,
//快速用户空间互斥锁),它允许进程等待,直到特定的条件为真,主要用于实现阻塞。
 
Atomics.wait()
//检查数组中指定位置的值是否仍然为给定值,如果是,则保持直到唤醒或超时。
//返回值为"ok", "not equal"或"time out"调用时,如果当前线程不允许阻塞,则抛出异常
//大多数浏览器不允许在主线程中调用wait()。
 
 
Atomics.wake()
//唤醒等待队列中等待数组中指定位置的元素的线程。返回值是成功唤醒的线程数
 
 
Atomics.isLockFree(size)
//它可用于检测当前系统是否支持硬件级原子操作。对于指定大小的数组,如果当前系统支持硬件级原子操作,
//返回true;否则,这意味着对于数组,Atomics对象中的每个原子操作只能通过一个锁实现。这个功能是为技术专家准备的。

4 ES9新特征 (2018)

  • Asynchronous iterator ( 异步迭代器)
  • 非转义序列的模板字符串
  • 反向正则表达式
  • 正则表达式Unicode转义
  • 正则表达式s/dotAll模式
  • 正则表达式命名捕获组
  • 对象扩展运算符
  • Promise.prototype.finally

4.1 asynchronous iterator (异步迭代器)

ES2018引入了异步迭代器,就像常规迭代器一样,只是next()方法返回一个Promise。因此,await可以与for…连用。的循环以串行方式运行异步操作。例如:

async function process(array) {
  for await (let i of array) {
    doSomething(i);
  }
}

4.2 非转义序列的模板字符串

标签允许你用函数解析模板字符串。tag函数的第一个参数包含一个字符串值数组。其余的参数依赖于表达式。最后,函数可以返回处理过的字符串(也可以返回完全不同的内容)。

function foo(str) {
    return str[0].toUpperCase();
}

foo`justjavac`; // Output JUSTJAVAC
foo`Xyz`; // Output XYZ

New features of ES2018: template string of non escape sequence

4.3 正则表达式反向断言

断言是对当前匹配位置之前或之后的字符进行测试。它实际上并不消耗任何字符,因此断言也被称为“非消耗匹配”或“非获取匹配”。

正则表达式断言有四种形式:

  • (? = pattern) 零宽度正向前视断言
  • (?! pattern) 零宽负向先行断言
  • (? < pattern) 零宽度正面看背后断言
  • (? <! Pattern) 零宽度负向后看断言

这里的模式是一个正则表达式。
Look behind assertion

4.4 正则表达式Unicode转义

一般来说,数字字符解释[0-9],单词字符是[0-9a-zA-Z],空白字符包括空格、回车和其他字符,但这是在ASCII编码中,而不是在Unicode编码中。

                                    . Therefore, if 在Python 2中指定正则表达式使用Unicode模式(最简单的解释方法是指定模式修饰符(?u)在正则表达式的开头),\ d \ w \ s可以匹配所有的角号、汉字和所有的角空格。在本例中,本书将其称为Unicode匹配规则;相应的,前面ASCII编码中的匹配称为ASCII匹配规则。
Regular expression -- Unicode matching rule

4.5 正则表达式s/dotAll模式

Regular expression s/dotAll mode

4.6 正则表达式命名捕获组

const
  reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
  match  = reDate.exec('2018-04-30'),
  year   = match.groups.year,  // 2018
  month  = match.groups.month, // 04
  day    = match.groups.day;   // 30
 
const
  reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
  d      = '2018-04-30',
  usDate = d.replace(reDate, '$<month>-$<day>-$<year>');

4.7 object expansion operator

let a = [1,2,3];
let b = [0, ...a, 4]; // [0,1,2,3,4]
 
let obj = { a: 1, b: 2 };
let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 }
let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }
let object = {
  a: '01', b: '02'
};
 
let newObject = {
  c: '03',
  ...object
};
 
console.log(newObject); //{c: "03", a: "01", b: "02"}

4.8 Promise.finally()

Promise调用链要么成功到达最后一个。则(),或无法触发。赶上()。在某些情况下,无论Promise运行成功还是失败,您都希望运行相同的代码,例如清除、删除对话、关闭数据库连接等。

function doSomething() {
  doSomething1()
  .then(doSomething2)
  .then(doSomething3)
  .catch(err => {
    console.log(err);
  })
  .finally(() => {
    // finish here!
  });
}

5  ES10 新特征 (2019)

  • 增加Array的flat()方法和flatMap()方法
  • 增加了String的trimStart()方法和trimEnd()方法
  • Object.fromEntries()
  • Symbol.prototype.description
  • String.prototype.matchAll
  • Function.prototype.toString()现在返回精确的字符,包括空格和注释
  • JSON⊂ECMAScript
  • 简化try {} catch{}并修改catch绑定
  • 新的基本数据类型BigInt
  • globalThis
  • import()
  • 遗留的正则表达式
  • 私有实例方法和访问器

5.1 添加Array的flat()方法和flatMap()方法

lat()和flatMap()本质上是reduce和concat的操作。
flat()方法递归地遍历指定深度的数组,并将遍历子数组中的所有元素和元素合并到要返回的新数组中。

  • flat()方法的基本功能是降低数组的维数
  • 其次,我们可以使用flat()方法的特性来删除数组中的空项

5.1.1 flat()

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]
 
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
 
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
 
//使用Infinity作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity); 
// [1, 2, 3, 4, 5, 6]
 
 
//删除空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

5.1.2 flatMap()

var arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

// 只将flatMap中函数返回的数组“flatten”
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

5.2 增加了String的trimStart()方法和trimEnd()方法

string. trimstart()可用于删除字符串开头的空格。

string. trimend()可用于删除字符串末尾的空格。

let  greeting =  "    Hello World";
console.log(greeting.trimStart());// "Hello World"

let greeting = "Hello World    ";
console.log(greeting.trimEnd());// "Hello World"

5.3 Object.fromEntries()

object .entries()方法的功能是返回给定对象的可枚举属性的键值对数组,其排列顺序与for…In循环用于遍历对象(不同之处在于for In循环还枚举原型链中的属性)。

Object.fromEntries() 与Object.entries()相反.

object . fromentries()函数传入键值对列表,并返回一个包含这些键值对的新对象。迭代形参应该是一个可以实现@ iterator方法并返回迭代器对象的对象。它生成一个类似数组的对象,其中包含两个元素,第一个是用作属性键的值,第二个是与属性键相关联的值。

  • 通过Object. fromentries, Map可以转换为Object:

const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
  • 通过Object. fromentries,你可以将Array转换为Object
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }

5.4 Symbol.prototype.description

只读描述属性,它是返回Symbol对象的可选描述的字符串。

let mySymbol = `My Symbol`;

let symObj = Symbol(mySymbol);

console.log(symObj) // Symbol(mySymbol);

console.log(String(symObj) === `Symbol(${mySymbol})`); // true

console.log(symObj.description); // "My Symbol"

5.5 String.protype.matchAll()

matchAll()方法返回一个迭代器,其中包含匹配字符串与正则表达式的所有结果,包括捕获组。

const string = 'Hexadecimal number:DEADBEEF CAFE'
const regex = '\b\p{ASCII_Hex_digit}+\b/gu'

for(const match of string.match(regex)) {
  console.log(Math)
}
/*
  output
  DEADBEEF
  CAFE
*/
// 2.字符串。matchAll给出关于每个匹配项的更详细信息
const string = 'Hexadecimal number:DEADBEEF CAFE'
const regex = '\b\p{ASCII_Hex_digit}+\b/gu'

for(const match of string.matchAll(regex)) {
  console.log(Math)
}
/*
 output
 ["DEADBEEF", index: 8, input: "Hexadecimal number: DEADBEEF CAFE", groups: undefind]
 ["CAFE", index: 17, input: "Hexadecimal number: DEADBEEF CAFE", groups: undefind] 
*/

5.6 Function.prototype.toString()现在返回精确的字符,包括空格和注释

toString()方法返回一个表示函数源代码的字符串。在ES6中,当在函数上调用toString时,它根据ECMAScript引擎返回函数的字符串表示形式。如果可能,它将返回源代码,否则返回一个标准化的占位符。

this.fruits = []
function buyFruits(fruit) {
  this.fruits = [...this.fruits, fruit]
}
console.log(buyFruits.toString())

/*
function buyFruits(fruit) {
  this.fruits = [...this.fruits, fruit]
}
*/

5.7 JSON⊂ECMAScript

在ES10之前的版本中,不接受非转义行分隔符U+2028和段落分隔符U+2029。

U+2028是段落分隔符。

U+2029为行分隔符。

let LS = ""
const PS = eval("'\u2029'")

5.8 简化try {} catch{}并修改catch绑定

可选的catch绑定允许开发人员在catch块中使用try/catch,而不使用error参数。

// Use before ES2019
try {
  // some code
}catch (err) {
  // 错误代码处理
}

// 现在像ES2019一样使用try / catch:
try  {
  // some code
}catch {
  // error handling code
}

5.9 新的基本数据类型BigInt

BigInt是第七个原语类型,它是一个精度任意的整数。而不仅仅是900719925474092的最大值。

猜你喜欢

转载自blog.csdn.net/qq_20173195/article/details/127117264