本文共 9473 字,大约阅读时间需要 31 分钟。
I think the V8 team at Google was waiting for this moment for a long time. The 8th version of the (the most popular JavaScript engine) is out! This new version comes with some really nice performance improvements and two new cool JavaScript language features: optional chaining and nullish coalescing.
我认为Google的V8团队已经等待了很长时间。 (最受欢迎JavaScript引擎)的第8个版本已经发布! 这个新版本具有一些非常不错的性能改进和两个新的很酷JavaScript语言功能:可选链接和无效合并。
This is a long-awaited feature. Let’s say you’re working with a terrible API provider. Let’s call this API CrocosAPI. CrocosAPI provides information about all the crocodiles in the world (it’s an unstable API every one knows ‘gators are superior to crocs’).
这是期待已久的功能。 假设您使用的是糟糕的API提供程序。 我们将此API称为CrocosAPI。 CrocosAPI提供有关世界上所有鳄鱼的信息(这是一个不稳定的API,每个人都知道“鳄鱼比鳄鱼更优越”)。
This is what our function to get a croc’s habitat (some crocodiles live in freshwater, brakish water and/or saltwater)
这就是我们获得鳄鱼栖息地的功能(一些鳄鱼生活在淡水,咸淡水和/或盐水中)
const getWaterHabitat = async (crocName) => { // First we call our made up api const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocName); // We get the responses body const crocInfo = crocResponse.body; // We access the water property of the habitat property return crocInfo.habitat.water;}// Let's get the water habitat of a crocodile called Barryconst barrysWaterHabitat = getWaterHabitat('Barry');// this returnsbarrysWaterHabitat == ['freshwater']
Now let’s say the developers of CrocosAPI decided to change the structure of their response from:
现在,假设CrocosAPI的开发人员决定将响应的结构从以下位置更改:
{ "personalInfo" : { "firstName" : "Barry" }, "habitat": { "water": ["freshwater"], } // ... skipping}
To:
至:
{ "personalInfo" : { "firstName" : "Barry" // ... }, // We changed 'habitat' to 'environment' "environment": { "water": ["freshwater"] } //...}
Now if we call getWaterHabitat
we will get:
现在,如果我们调用getWaterHabitat
我们将获得:
TypeError: Cannot read property 'water' of undefined
That’s because crocInfo.habitat
doesn’t exist anymore. Now to access crocInfo
, we have to access crocInfo.environment.water
. This means our entire app will crash just because CrocosAPI’s developers don’t know about versioning. So how to avoid that error? Optional chaining of course!
这是因为crocInfo.habitat
不再存在。 现在访问crocInfo
,我们必须访问crocInfo.environment.water
。 这意味着我们的整个应用程序将仅因为CrocosAPI的开发人员不知道版本控制而崩溃。 那么如何避免该错误呢? 当然可选链!
const getWaterHabitat = async (crocName) => { const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocName) const crocInfo = crocResponse.body // We access the water key with optional chaining return crocInfo?.habitat?.water}const myCrocsName = 'Barry'const barrysWaterHabitat = getWaterHabitat('Barry')// barrysWaterHabitat == undefined
You can also use optional indexing with arrays:
您还可以对数组使用可选索引:
const crocAddress1City = crocInfo?.personalInfo?.addresses?.[0].city// if crocInfo.personalInfo.addresses = []// crocAddress1City === undefined
… And with functions!
…并具有功能!
// It is hard to make a short exampleconst getSkinStyle = (option) => { const scales = { color: 'green', texture: 'shiny' } if (option == 'naked') return else return scales}const crocInfo = { name: 'Barry', waterHabitat : 'Freshwaters', getSkinStyle : getSkinStyle}const barrysSkinColor = crocInfo?.getSkinStyle?.('naked')?.color// barrysSkinColor === undefinedconst larrysSkinColor = crocInfo?.getSkinStyle?.('naked')?.color// larrysSkinColor === 'green'
…And with dynamic property access. Wow, it really is holiday season ⛄🎄🎁 (at the time of the writing)!
…并具有动态属性访问权限。 哇,确实是假期season(在撰写本文时)!
// habitatType can be "water" or "land"const getHabitatProperty = (habitatType) => { return crocInfo?.habitat?.[habitatType]}getHabitatType('water')// returns ['freshwater']getHabitatType('land')// returns ['forest']
No more type errors anymore, just an undefined
value!
不再有类型错误,只是一个undefined
值!
As a quick PSA, don’t rely on optional chaining as an excuse not to do proper error handling. The good thing about the TypeError we get from accessing the property of an undefined value is that:
作为一种快速的PSA,请勿以可选链接为借口,以不进行适当的错误处理。 通过访问未定义值的属性而得到的TypeError的好处是:
We should still have some sort of fallback or warning mechanism when trying to access the property of an undefined value.
尝试访问未定义值的属性时,我们仍应具有某种后备或警告机制。
??
… No I’m not confused, ??
is the new short-circuit operator joining the &&
and ||
family. If you wrote some React, Vue or Angular you have probably already written or seen something like this.
??
……不,我不感到困惑, ??
是加入&&
和||
的新的短路算子 家庭。 如果您编写了一些React,Vue或Angular,您可能已经编写或看到过类似的内容。
const name = props.name || 'CrocName Error';const age = props.age || 'Invalid Age';const isFemale = props.isFemale || true;// pass name , age and isFemale to a view
This code will assign the value stored in props.name
if it’s not falsy. If the value is falsy, the value name
will equal CrocName Error
.
如果不是伪造的,此代码将分配存储在props.name
的值。 如果值是伪造的,则值name
将等于CrocName Error
。
But let’s say that for crocodiles who still haven’t been named, the API returns an empty string. In JavaScript, an empty string is considered falsy so this will happen:
但是,对于尚未命名的鳄鱼,API返回一个空字符串。 在JavaScript中,空字符串被认为是虚假的,因此会发生这种情况:
// Let's say we have an anonymous new born boy crocodileconst props = { name: '', age: 0, isFemale: false}const name = props.name || 'CrocName Error';// name === 'CrocName Error'const age = props.age || 'Invalid Age';// age === 'Invalid Age'const isFemale = props.isFemale || true;// isFemale === true
These are not the results we were expecting! We want to separate the scenario where props.name
has a null
or undefined
value to the case where props.name
is an empty string. We want age
to equal 0
and isFemale
to be false
. That’s where ??
comes to the rescue.
这些不是我们期望的结果! 我们要将props.name
为null
或undefined
值的情况与props.name
为空字符串的情况props.name
。 我们希望age
等于0
而isFemale
为false
。 那是哪里??
来救援。
const name = '' ?? 'CrocName Error'// name === '' const age = 0 ?? 'Invalid Age';// age === 0const isFemale = false ?? true;// isFemale === false// Yay it worked!
||
checks if the left hand side operator is falsy. ??
only checks if it is null
or undefined
. Here is a little cheat sheet for you:
||
检查左侧运算符是否虚假。 ??
只检查它是否为null
或undefined
。 这是给您的一些备忘单:
// +0, -0, NaN, false, empty strings, null and undefined are all falsyfalse ?? true; // equals falsefalse || true; // equals true0 ?? 1; // equals 00 || 1; // equals 1'' ?? 'default'; // equals '''' || 'default'; // equals 'default'// null and undefined are falsy so in this case we get the same resultsnull ?? []; // equals []null || []; // equals []undefined ?? []; // equals []undefined || []; // equals []
You can also mix operators! Just remember to use parenthesis. Try to think about what this would do:
您还可以混合使用运算符! 只要记住要使用括号即可。 尝试考虑一下该怎么做:
const crocName = (props.name ?? 'CrocName Error') || 'Anonymous Croc';
Let’s look at the result of a few values:
让我们看几个值的结果:
props.name === 'Barry'
: crocName === 'Barry'
props.name === 'Barry'
: crocName === 'Barry'
props.name === ''
: crocName ==== 'Anonymous Croc'
props.name === ''
: crocName ==== 'Anonymous Croc'
props.name === undefined
: crocName ==== 'CrocName Error'
props.name === undefined
: crocName ==== 'CrocName Error'
You might have thought of cool ways to use these two features together!
您可能已经想到了同时使用这两个功能的好方法!
const getCrocName = async (crocId) => { // We try to access our unstable API's data const crocResponse = await fetch('http://api.crocosapi.io/croc/' + crocId) // If croc response or body is undefined const crocInfo = crocResponse?.body ?? 'Croc API did not return a valid response' // if crocResponse equals {} then crocInfo == 'Croc API did not return a valid response' // checking if crocInfo, personal info or name is undefined/null or if name has a falsy value return (crocInfo?.personalInfo?.name ?? 'There was a problem loading the croc\'s name') || 'Anonymous Croc' // if crocInfo?.personalInfo?.name === '' we return 'Anonymous Croc' // if crocInfo equals {} we return 'There was a problem loading the croc\'s name'}
Nowadays we are spoiled with how fast JavaScript is and even more spoiled by recurrent performance updates. Once again, V8’s engineers improved the performance and memory of their engine. If you’re interested in learning more about how that is, you can check out . The thing I love about these updates is that it improves our code performance, but we don’t have to write anything new!
如今,我们对JavaScript的速度如此之快感到迷恋,甚至由于周期性的性能更新而更加受宠。 V8的工程师再次提高了引擎的性能和内存。 如果您有兴趣了解更多有关它的信息,可以查看 。 我喜欢这些更新,因为它可以提高我们的代码性能,但是我们不必编写任何新内容!
To check if you can use V8 v8 in Node.jd you can run node -p process.versions.v8
and see if the version is over 8. For now you should use polyfills like on the web and/or a transpiler. If you’re using Babel, @babel/plugin-proposal-optional-chaining
, @babel/plugin-proposal-nullish-coalescing-operator
are available.
要检查是否可以在Node.jd中使用V8 v8,可以运行node -p process.versions.v8
并查看版本是否超过8。现在,您应该在Web和/或Transpiler上使用诸如之类的polyfills。 。 如果您使用的是Babel,则@babel/plugin-proposal-optional-chaining
, @babel/plugin-proposal-nullish-coalescing-operator
可用。
Have fun and happy holidays! 🎄🎉
祝您节日快乐! 🎄🎉
翻译自:
转载地址:http://zlhgb.baihongyu.com/