JavaScript:从 ES2016 到 ES2019 的所有内容
大家好,我是 Alberto Montalesi,一位自学成才的全栈开发者。我在我的网站inspiredwebdev.com上创建实用的 JavaScript 教程和课程,旨在激励其他开发者成长,并打造他们理想的职业。
JavaScript
是一种不断发展的语言,在过去的几年中,许多新功能被添加到ECMAScript
规范中。
本文摘自我的书《现代 JavaScript 完全指南》,其中涵盖了 ES2016、ES2017、ES2018、ES2019 的新增内容,最初发布在我的博客inspiredWebDev上。
在文章的最后,您将找到一个下载总结所有内容的备忘单的链接。
ES2016 的所有新功能
ES2016 仅引入了两个新功能:
Array.prototype.includes()
- 指数运算符
Array.prototype.includes()
如果我们的数组包含某个元素,则该includes()
方法将返回,否则返回。true
false
let array = [1,2,4,5];
array.includes(2);
// true
array.includes(3);
// false
结合includes()
fromIndex
我们可以提供.includes()
索引来开始搜索元素。默认值为 0,但也可以传递负值。
我们传入的第一个值是要搜索的元素,第二个值是索引:
let array = [1,3,5,7,9,11];
array.includes(3,1);
// find the number 3 starting from array index 1
// true
array.includes(5,4);
//false
array.includes(1,-1);
// find the number 1 starting from the ending of the array going backwards
// false
array.includes(11,-3);
// true
array.includes(5,4);
返回的false
原因是,尽管数组包含数字 5,但它位于索引 2 处,而我们开始查看位置 4。这就是为什么我们找不到它并且它返回的原因false
。
array.includes(1,-1);
返回false
是因为我们从索引 -1(数组的最后一个元素)开始查看,然后从该点继续向前。
array.includes(11,-3);
返回true
是因为我们回到索引 -3 并向上移动,在路径上找到了值 11。
指数运算符
在 ES2016 之前,我们会做以下事情:
Math.pow(2,2);
// 4
Math.pow(2,3);
// 8
现在使用新的指数运算符,我们可以执行以下操作:
2**2;
// 4
2**3;
// 8
当组合多个操作时它会变得非常有用,如下例所示:
2**2**2;
// 16
Math.pow(Math.pow(2,2),2);
// 16
使用时,Math.pow()
你需要不断地将它们连接起来,这会变得非常冗长和混乱。指数运算符提供了一种更快、更简洁的方式来完成同样的操作。
ES2017字符串填充Object.entries()
等Object.values()
ES2017 引入了许多很酷的新功能,我们将在这里看到。
字符串填充(.padStart()
和.padEnd()
)
我们现在可以在字符串的末尾(.padEnd()
)或开头(.padStart()
)添加一些填充。
"hello".padStart(6);
// " hello"
"hello".padEnd(6);
// "hello "
我们指定了 6 作为填充,那么为什么在两种情况下都只得到了 1 个空格呢?
这是因为padStart
和padEnd
会去填充空格。在我们的例子中,“hello”有 5 个字母,而我们的填充是 6,所以只留下 1 个空格。
看这个例子:
"hi".padStart(10);
// 10 - 2 = 8 empty spaces
// " hi"
"welcome".padStart(10);
// 10 - 6 = 4 empty spaces
// " welcome"
右对齐padStart
padStart
如果我们想右对齐某些内容,我们可以使用。
const strings = ["short", "medium length", "very long string"];
const longestString = strings.sort(str => str.length).map(str => str.length)[0];
strings.forEach(str => console.log(str.padStart(longestString)));
// very long string
// medium length
// short
首先,我们取出最长的一根绳子并测量它的长度。然后,我们padStart
根据最长绳子的长度对所有绳子应用了a,这样现在所有绳子都完美地向右对齐了。
向填充添加自定义值
我们不必只添加空格作为填充,我们可以传递字符串和数字。
"hello".padEnd(13," Alberto");
// "hello Alberto"
"1".padStart(3,0);
// "001"
"99".padStart(3,0);
// "099"
Object.entries()
和Object.values()
让我们首先创建一个对象。
const family = {
father: "Jonathan Kent",
mother: "Martha Kent",
son: "Clark Kent",
}
在以前的版本中,JavaScript
我们会像这样访问对象内部的值:
Object.keys(family);
// ["father", "mother", "son"]
family.father;
"Jonathan Kent"
Object.keys()
仅返回我们必须用来访问值的对象的键。
我们现在有两种访问对象的方法:
Object.values(family);
// ["Jonathan Kent", "Martha Kent", "Clark Kent"]
Object.entries(family);
// ["father", "Jonathan Kent"]
// ["mother", "Martha Kent"]
// ["son", "Clark Kent"]
Object.values()
返回所有值的数组,同时Object.entries()
返回包含键和值的数组数组。
Object.getOwnPropertyDescriptors()
此方法将返回对象的所有自身属性描述符。它可以返回的
属性有value
、writable
、get
、和。set
configurable
enumerable
const myObj = {
name: "Alberto",
age: 25,
greet() {
console.log("hello");
},
}
Object.getOwnPropertyDescriptors(myObj);
// age:{value: 25, writable: true, enumerable: true, configurable: true}
// greet:{value: ƒ, writable: true, enumerable: true, configurable: true}
// name:{value: "Alberto", writable: true, enumerable: true, configurable: true}
函数参数列表和调用中的尾随逗号
这只是语法上的一个小改动。现在,在编写对象时,我们可以在每个参数后留一个逗号,无论它是否是最后一个参数。
// from this
const object = {
prop1: "prop",
prop2: "propop"
}
// to this
const object = {
prop1: "prop",
prop2: "propop",
}
注意我在第二个属性的末尾加了一个逗号。
如果不加逗号,也不会报错,但最好还是遵循这个做法,这样可以方便你的同事或团队成员。
// I write
const object = {
prop1: "prop",
prop2: "propop"
}
// my colleague updates the code, adding a new property
const object = {
prop1: "prop",
prop2: "propop"
prop3: "propopop"
}
// Suddenly, he gets an error because he did not notice that I forgot to leave a comma at the end of the last parameter.
共享内存和Atomics
来自MDN:
共享内存时,多个线程可以读写内存中的相同数据。原子操作可确保写入和读取的值是可预测的,操作在下一个操作开始之前完成,并且操作不会被中断。
Atomics
不是构造函数,它的所有属性和方法都是静态的(就像Math
),因此我们不能将它与新运算符一起使用或将Atomics
对象作为函数调用。
其方法示例如下:
- 添加/订阅
- 与/或/异或
- 加载/存储
原子与(通用固定长度二进制数据缓冲区)对象一起使用,SharedArrayBuffer
这些对象表示通用的、固定长度的原始二进制数据缓冲区。
让我们看一些Atomics
方法的示例:
Atomics.add()
,Atomics.sub()
,Atomics.load()
和Atomics.store()
Atomics.add()
将采用三个参数:一个数组、一个索引和一个值,并在执行加法之前返回该索引处的先前值。
// create a `SharedArrayBuffer`
const buffer = new SharedArrayBuffer(16);
const uint8 = new Uint8Array(buffer);
// add a value at the first position
uint8[0] = 10;
console.log(Atomics.add(uint8, 0, 5));
// 10
// 10 + 5 = 15
console.log(uint8[0])
// 15
console.log(Atomics.load(uint8,0));
// 15
如您所见,调用Atomics.add()
将返回我们所针对的数组位置的先前值。当我们再次调用时,uint8[0]
我们会看到执行了加法并得到了 15。
要从数组中检索特定值,我们可以使用Atomics.load
并传递两个参数、一个数组和一个索引。
Atomics.sub()
工作方式相同,Atomics.add()
但它会减去一个值。
// create a `SharedArrayBuffer`
const buffer = new SharedArrayBuffer(16);
const uint8 = new Uint8Array(buffer);
// add a value at the first position
uint8[0] = 10;
console.log(Atomics.sub(uint8, 0, 5));
// 10
// 10 - 5 = 5
console.log(uint8[0])
// 5
console.log(Atomics.store(uint8,0,3));
// 3
console.log(Atomics.load(uint8,0));
// 3
这里我们使用Atomics.sub()
从位置的值中减去 5,uint8[0]
相当于 10 - 5。
与 相同Atomics.add()
,该方法将返回该索引处的前一个值,在本例中为 10。
然后,我们使用它Atomics.store()
来存储特定的值,在本例中为 3,在数组的特定索引处,在本例中为 0,即第一个位置。Atomics.store()
将返回我们刚刚传递的值,在本例中为 3。您可以看到,当我们调用Atomics.load()
该特定索引时,我们得到的是 3,而不是 5。
Atomics.and()
,Atomics.or()
和Atomics.xor()
这三种方法均在数组的给定位置执行按位与、或和异或运算。您可以在维基百科的链接https://en.wikipedia.org/wiki/Bitwise_operation上了解有关位运算的更多信息。
ES2017 Async 和 Await
非常感谢你的阅读。欢迎在DevTo、博客inspiredwebdev或Twitter上关注我。
免责声明:亚马逊和 Educative 的链接为联盟链接,您的购买将为我带来额外佣金。谢谢
文章来源:https://dev.to/albertomontalesi/javascript-everything-from-es2016-to-es2019-246c