今天,我们将发布JavaScript创新的第二部分。 在这里,我们谈论数字的分隔符,关于
globalThis
数字,关于使用数组和对象,关于
globalThis
,关于排序,关于国际化API以及关于promises的问题。

→
第一部分数字分隔符
程序中发现的长数字很难阅读。 例如,
1000000000
是十进制的十亿。 但乍一看很难理解。 因此,如果程序的读者遇到类似的情况-为了正确地理解它,他将必须仔细考虑零。
在现代JavaScript中,您可以使用数字的分隔符-下划线(
_
),使用下划线可以提高长数字的可读性。 这是使用定界符编写的数字在代码中的显示方式:
var billion = 1_000_000_000; console.log( billion );
分隔符可用于将数字任意划分为多个片段。 JavaScript在处理数字时,只会忽略分隔符。 在写任何数字时可以使用它们:整数,浮点数,二进制,十六进制,八进制。
console.log( 1_000_000_000.11 );
→支持
Bigint数据类型
JavaScript中的数字是使用
Number
构造函数创建的。
使用
Number
数据类型可以安全表示的最大值是(2⁵³-1),即9007199254740991。您可以使用
Number.MAX_SAFE_INTEGER
构造查看此数字。
请注意,当在JS代码中使用数字文字时,JavaScript将对其进行处理,并使用
Number
构造函数基于该文字创建对象。 该对象的原型包含使用数字的方法。 所有
原始数据类型都会发生这种情况。
如果我们尝试在数字9007199254740991中添加一些内容,将会怎样?
console.log( Number.MAX_SAFE_INTEGER );
将
Number.MAX_SAFE_INTEGER
和
console.log()
的第二个输出10相加的结果不正确。 这是由于JS无法正确执行大于
Number.MAX_SAFE_INTEGER
数字的计算。 您可以使用
bigint
数据
bigint
来解决此问题。
bigint
类型允许
bigint
表示大于
Number.MAX_SAFE_INTEGER
整数。 使用BigInt值类似于使用
Number
类型的
Number
。 尤其是,该语言具有
BigInt()
函数,您可以使用该函数创建相应的值,以及内置的原始
bigint
数据类型用于表示大整数。
var large = BigInt( 9007199254740991 ); console.log( large );
JavaScript在BigInt文字的末尾添加
n
。 对我们来说,这意味着可以通过在整数的末尾加上
n
来编写此类文字。
现在我们有了BigInt数,可以安全地对大量
bigint
类型执行数学运算。
var large = 9007199254740991n; console.log( large + 10n );
类型
number
的数字与类型
bigint
的数字不同。 特别是,我们谈论的是BigInt-numbers只能是整数的事实。 结果,事实证明您无法执行使用
bigint
和
number
类型的算术运算。
应当注意,
BigInt()
函数可以采用各种数字:十进制,二进制,十六进制,八进制。 在此函数内部,它们将转换为数字,使用十进制数字系统表示。
bigint
类型还支持位分隔符:
var large = 9_007_199_254_741_001n; console.log( large );
→支持
- TC39: 阶段3
- 铬: 67+
- 节点:10.4+
- Firefox:68+
新的数组方法:.flat()和.flatMap()
在这里,我们将讨论
Array
对象的新原型方法
.flat()
和
.flatMap()
方法。
flat .flat()方法
现在,
Array
类型的对象有了一个新方法
.flat(n)
。 它返回一个新数组,以递归方式将数组的元素提升到指定的级别
n
。 默认情况下,
n
为1。此方法可以传递等于
Infinity
n
,这使您可以将具有嵌套数组的数组转换为一维数组。
var nums = [1, [2, [3, [4, 5]]]]; console.log( nums.flat() );
→支持
- TC39: 第4阶段
- 铬: 69+
- 节点:11岁以上
- Firefox:62岁以上
flat .flatMap()方法
在解决日常任务时,程序员有时可能需要使用
.map()
方法处理数组,然后将其转换为平面结构。 例如,创建一个包含这些数字和这些数字的平方的数组:
var nums = [1, 2, 3]; var squares = nums.map( n => [ n, n*n ] ) console.log( squares );
通过使用
.flatMap()
方法,可以简化此问题的解决方案。 它将转换传递给它的回调函数返回的数组,就像转换其参数
n
等于1的
.flat()
方法一样。
var nums = [1, 2, 3]; var makeSquare = n => [ n, n*n ]; console.log( nums.flatMap( makeSquare ) );
→支持
- TC39: 第4阶段
- 铬: 69+
- 节点:11岁以上
- Firefox:62岁以上
▍Object.fromEntries()方法
可以从一个对象中提取
:
类型对
:
可以使用静态的Method
Object
来使用
:
,该方法返回一个数组,该数组的每个元素都是一个数组,其中包含一个键(第一个元素),第二个元素包含一个值。
var obj = { x: 1, y: 2, z: 3 }; var objEntries = Object.entries( obj ); console.log( objEntries );
现在我们可以使用一个静态方法
Object.fromEntries()
,它允许我们将类似的结构转换回一个对象。
var entries = [["x", 1],["y", 2],["z", 3]]; var obj = Object.fromEntries( entries ); console.log( obj );
entries()
方法用于促进对存储在对象中的数据进行过滤和映射。 结果是一个数组。 但是到目前为止,将这样的数组转换为对象的任务还没有很好的解决方案。 可以使用
Object.fromEntries()
方法来解决此问题。
var obj = { x: 1, y: 2, z: 3 };
如果
Map
:
数据结构用于存储对
:
,那么其中的数据将按照它们添加到其中的顺序进行存储。 同时,数据的存储方式类似于
Object.entries()
方法返回的数组。
Object.fromEntries()
方法
Object.fromEntries()
很容易用于将
Map
数据结构转换为对象。
var m = new Map([["x", 1],["y", 2],["z", 3]]); console.log( m );
→支持
▍全球房地产globalThis
我们熟悉JavaScript中使用的
this
。 它没有固定值。 而是,其含义取决于对其进行访问的上下文。 在任何环境中,从最高级别的上下文访问
this
时,它都指向一个全局对象。 这就是这个的全球意义。
例如,在基于浏览器的JavaScript中,其全局值是
window
对象。 您可以使用JavaScript文件的顶级(在最外部的上下文中)或在浏览器JS控制台中使用
console.log(this)
构造来验证这一点。
在浏览器控制台中访问它Node.js中
this
的全局值指向一个
global
对象。 在网络工作者内部,它指向工作者本人。 但是,要获得这一全球价值并非易事。 事实是,您无法在任何地方引用
this
。 例如,如果您尝试在类的构造函数中执行此操作,那么事实证明
this
指向相应类的实例。
在某些环境中,
self
this
可用于访问
this
的全局值。 该关键字与在浏览器,Node.js和Web Worker中访问此值的机制相同。 使用关于如何在不同环境中调用
this
方法的全局值的知识,可以创建一个返回此值的函数:
const getGlobalThis = () => { if (typeof self !== 'undefined') return self; if (typeof window !== 'undefined') return window; if (typeof global !== 'undefined') return global; if (typeof this !== 'undefined') return this; throw new Error('Unable to locate global `this`'); }; var globalThis = getGlobalThis();
在我们面前的是一个原始的polyfill,用于获取
this
对象的全局信息。
在此处阅读有关此内容的更多信息。 JavaScript现在具有
globalThis
关键字。 它提供了一种访问不同环境的全局值的通用方法,并且不依赖于从中访问该程序的程序的位置。
var obj = { fn: function() { console.log( 'this', this === obj );
→支持
- TC39: 阶段3
- 铬: 71+
- 节点:12岁以上
- Firefox:65岁以上
排序稳定
ECMAScript标准未提供JavaScript引擎应实现的特定数组排序算法。 它仅描述用于排序的API。 结果,使用不同的JS引擎,可能会遇到排序操作的性能和排序算法的稳定性(稳定性)方面的差异。
现在,该标准
要求排序数组必须稳定。 有关分类稳定性的详细信息,请参见
此处 。 排序算法的这一特征的实质如下。 如果排序结果是一个经过修改的数组,则该算法是稳定的,该排序结果包含的元素具有相同的值,这些元素的值不受排序的影响,排序的顺序与它们在原始数组中的放置顺序相同。 考虑一个例子:
var list = [ { name: 'Anna', age: 21 }, { name: 'Barbra', age: 25 }, { name: 'Zoe', age: 18 }, { name: 'Natasha', age: 25 } ];
在这里,包含对象的
list
数组按这些对象的
age
字段排序。 在
list
数组中,
name
属性等于
Barbra
的对象位于
name
属性等于
Natasha
的对象之前。 由于这些对象的
age
值相等,因此我们可以期望在排序后的数组中这些元素将相对于彼此保留以前的排列顺序。 但是,实际上这是无法预期的。 排序数组的精确形成方式完全取决于所使用的JS引擎。
现在,所有现代浏览器和Node.js都使用一种稳定的排序算法,该算法在访问
.sort()
数组方法时调用。 这样一来,对于相同的数据,您总是可以得到相同的结果:
过去,某些JS引擎支持稳定排序,但仅适用于小型数组。 为了提高处理大型阵列时的性能,它们可以使用更快的算法并牺牲排序稳定性。
→支持
- 铬: 70+
- 节点:12岁以上
- Firefox:62岁以上
国际化API
国际化API旨在组织字符串比较,以格式化数字,日期和时间,这是各种区域标准(区域设置)的惯例。 通过
Intl
对象可以组织对此API的访问。 该对象提供了用于创建排序器对象和格式化数据的对象的构造函数。 可在
此处找到
Intl
对象支持的语言环境列表。
tlIntl.RelativeTimeFormat()
在许多应用中,通常需要以相对格式输出时间。 它可能看起来像是“ 5分钟前”,“昨天”,“ 1分钟前”等等。 如果将网站资料翻译成不同的语言,则必须在网站组合中包括描述时间的所有可能的相对结构组合。
JS现在具有
Intl.RelativeTimeFormat(locale, config)
构造函数 ,该
构造函数使您可以为不同的语言环境创建日期和时间格式设置系统。 特别是,我们谈论的对象具有
.format(value, unit)
,该方法使您可以生成各种相对时间戳。 看起来像这样:
→支持
- TC39: 阶段3
- 铬: 71+
- 节点:12岁以上
- Firefox:65岁以上
tlIntl.ListFormat()
Intl.ListFormat
构造函数使
Intl.ListFormat
可以使用单词
and
(
)和
or
(
)组合列表项。 创建相应的对象时,构造函数将被传递给语言环境和带有参数的对象。 其
type
参数可以是
conjunction
,
disjunction
和
unit
。 例如,如果要使用连接对象来合并
[apples, mangoes, bananas]
的元素,我们将得到
apples, mangoes and bananas
形式的字符串。 如果使用析取对象,则会得到一串
apples, mangoes or bananas
。
由
Intl.ListFormat
构造函数创建的对象具有组合列表
的 .format(list)
方法 。 考虑一个例子:
→支持
Local国际语言环境()
通常,“区域标准”的概念不仅仅是一种语言的名称。 这可能包括日历的类型,有关使用的时间周期的信息以及语言名称。
Intl.Locale(localeId, config)
构造函数 Intl.Locale(localeId, config)
用于基于传递给它的
config
对象创建格式化的
Intl.Locale(localeId, config)
字符串。
使用
Intl.Locale
创建
Intl.Locale
对象包含所有指定的区域设置。 其
.toString()
方法产生格式化的区域标准字符串。
const krLocale = new Intl.Locale( 'ko', { script: 'Kore', region: 'KR', hourCycle: 'h12', calendar: 'gregory' } ); console.log( krLocale.baseName );
在这里,您可以阅读有关Unicode中的标识符和语言环境标签的信息。
→支持
承诺
到目前为止,JS具有静态方法
Promise.all()
和
Promise.race()
。
Promise.all([...promises])
方法返回一个promise,该promise将作为参数传递给该方法的所有promise解析成功。 如果转移给它的承诺中的至少一个被拒绝,则该承诺被拒绝。
Promise.race([...promises])
方法返回一个promise,在任何传递给它的promise被解析后,该promise将被解析,如果其中至少一个promise被拒绝,则被拒绝。
JS开发人员社区迫切需要一个静态方法,返回的诺言将在传递给它的所有诺言完成(允许或拒绝)之后得到解决。 另外,我们需要一种类似于
race()
的方法,该方法将返回一个promise,等待传递给它的任何promise的解析。
m Promise.allSettled()方法
Promise.allSettled()
方法接受一个promise数组。 在所有承诺都被拒绝或允许之后,才允许他返回的承诺。 结果是此方法返回的promise不需要
catch
。
事实是,这一诺言总是能够成功解决。
then
块按照它们出现的顺序从每个承诺中接收
status
和
value
。
var p1 = () => new Promise( (resolve, reject) => setTimeout( () => resolve( 'val1' ), 2000 ) ); var p2 = () => new Promise( (resolve, reject) => setTimeout( () => resolve( 'val2' ), 2000 ) ); var p3 = () => new Promise( (resolve, reject) => setTimeout( () => reject( 'err3' ), 2000 ) ); var p = Promise.allSettled( [p1(), p2(), p3()] ).then( ( values ) => console.log( values ) );
→支持
▍方法Promise.any()
Promise.any()
方法类似于
Promise.race()
,但是当传递给此方法的一个承诺被拒绝时,它返回的承诺不会执行
catch
。
相反,他等待所有诺言的解决。 如果没有允诺,那么
catch
块将被执行。 如果任何诺言都成功解决,则将执行。
总结
在本文中,我们研究了
Google I / O 2019大会上讨论的一些JavaScript创新。 我们希望您在其中找到对您有用的东西。
亲爱的读者们! 您在JavaScript中特别想念什么?
