Web培训
400-996-5531
今天小编要跟大家分享的文章是关于JavaScript的 新特性。在本文中小编主要为大家介绍了JavaScript中一些新特性,包括它们的语法和相关链接,帮助读者及时了解它们的进度,我们将通过编写一个小型测试项目,展示如何快速上手使用这些新特性!下面让我们一起来看一看吧!
创建测试项目
新建一个目录并运行运行以下命令:
npm init -f
npm i ava@1.0.0-beta.3 @babel/preset-env@7.0.0-beta.42 @babel/preset-stage-0@7.0.0-beta.42 @babel/register@7.0.0-beta.42 @babel/polyfill@7.0.0-beta.42 @babel/plugin-transform-runtime@7.0.0-beta.42 @babel/runtime@7.0.0-beta.42 --save-dev`
然后将以下内容添加到package.json文件中:
{ "scripts": { "test": "ava" }, "ava": { "require": [ "@babel/register", "@babel/polyfill" ] } } 最后创建一个.babelrc文件: { "presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } } ], "@babel/preset-stage-0" ], "plugins": [ "@babel/plugin-transform-runtime" ] }
现在可以开始写一些测试用例了!
1、可选运算符
在JavaScript中,我们一直在使用对象,但有时候对象里并不是我们期望的数据结构。假设下面是我们期望得到的数据,可能是通过调用API查询数据库得到的。
const data = { user: { address: { street: "Pennsylvania Avenue" } } }
如果该用户没有完成注册,可能得到下面的数据:
const data = { user: {} };
当尝试按下面的方式访问street时,会得到报错:
console.log(data.user.address.street);
// Uncaught TypeError: Cannot read property 'street' of undefined
为避免这种情况,需要按如下方式访问“street”属性:
const street = data && data.user && data.user.address && data.user.address.street;
console.log(street); // undefined`
在我看来,这种方法:
1. 不美观
2. 繁重
3. 啰嗦
如果使用可选运算符,可以这样编码:
console.log(data.user?.address?.street); // undefined
这样看起来更简单了,现在我们已经看到了这个功能的用处,现在来写一个测试!
import test from 'ava'; const valid = { user: { address: { street: 'main street', }, }, }; function getAddress(data) { return data?.user?.address?.street; } test('Optional Chaining returns real values', (t) => { const result = getAddress(valid); t.is(result, 'main street'); });
我们看到了可选符号的正常使用,接下来是一些不规范数据的测试用例:
test('Optional chaining returns undefined for nullish properties.', (t) => { t.is(getAddress(), undefined); t.is(getAddress(null), undefined); t.is(getAddress({}), undefined); });
用于访问数组元素的用例:
const valid = { user: { address: { street: 'main street', eighbors: [ 'john doe', 'jane doe', ], }, }, }; function getNeighbor(data, number) { return data?.user?.address?.neighbors?.[number]; } test('Optional chaining works for array properties', (t) => { t.is(getNeighbor(valid, 0), 'john doe'); }); test('Optional chaining returns undefined for invalid array properties', (t) => { t.is(getNeighbor({}, 0), undefined); });
有时我们不知道某个函数是否在对象中实现,一个常见的场景是,某些旧版浏览器可能没有某些功能,我们可以使用可选运算符接来检测函数是否已实现。看如下代码:
const data = { user: { address: { street: 'main street', eighbors: [ 'john doe', 'jane doe', ], }, getNeighbors() { return data.user.address.neighbors; } }, }; function getNeighbors(data) { return data?.user?.getNeighbors?.(); } test('Optional chaining also works with functions', (t) => { const neighbors = getNeighbors(data); t.is(neighbors.length, 2); t.is(neighbors[0], 'john doe'); }); test('Optional chaining returns undefined if a function does not exist', (t) => { const neighbors = getNeighbors({}); t.is(neighbors, undefined); });
如果调用链不完整,函数将不会执行,它背后的逻辑应该是这样的:
value == null ? value[some expression here]: undefined;
如果在可选链操作符之后是 undefined 或者 null则什么都不会执行,我们可以在以下测试中看到该规则的实际应用:
let neighborCount = 0; function getNextNeighbor(neighbors) { return neighbors?.[++neighborCount]; } test('It short circuits expressions', (t) => { const neighbors = getNeighbors(data); t.is(getNextNeighbor(neighbors), 'jane doe'); t.is(getNextNeighbor(undefined), undefined); t.is(neighborCount, 1); });
有了可选运运算符,我们的代码中可以减少if语句、lodash等库以及&&进行链式调用的使用。
2、空值合并
以下是我们在JavaScript中看到的一些常见操作:
1. 检查 null 或 undefined
2. 给变量设置默认值
3. 确保0,false和''不设置默认值
像这样:
value != null ? value : 'default value';
或者这样:
value || 'default value'
问题是,对于第二个实现,在值为0、false和''时都被视为false,所以我们必须明确检查null和undefined。
value != null
和上面相同:
value !== null && value !== undefined
这就是新提案的用武之地,现在我们可以这样做:
value ?? 'default value';
这可以保护我们不会为0、false和''设置默认值,在不使用三元运算符和!= null检查的情况下捕获null和undefined。
接下来编写一个简单的测试来验证它是如何工作的:
import test from 'ava'; test('Nullish coalescing defaults null', (t) => { t.is(null ?? 'default', 'default'); }); test('Nullish coalescing defaults undefined', (t) => { t.is(undefined ?? 'default', 'default'); }); test('Nullish coalescing defaults void 0', (t) => { t.is(void 0 ?? 'default', 'default'); }); test('Nullish coalescing does not default 0', (t) => { t.is(0 ?? 'default', 0); }); test('Nullish coalescing does not default empty strings', (t) => { t.is('' ?? 'default', ''); }); test('Nullish coalescing does not default false', (t) => { t.is(false ?? 'default', false); });
在测试中看到,??为null,undefined和void 0设置了默认值,没有为0,''和false设置默认值。
3、管道运算符
在函数式编程中,我们有一个概念叫compose,它多个函数调用合并在一起,调用时从右到左执行每个函数,函数接收前一个函数的输出作为其输入,以下是我们在纯JavaScript中讨论的一个示例:
function doubleSay (str) { return str + ", " + str; } function capitalize (str) { return str[0].toUpperCase() + str.substring(1); } function exclaim (str) { return str + '!'; } let result = exclaim(capitalize(doubleSay("hello"))); result //=> "Hello, hello!"
这种合并使用函数的方式很常见常见,以至于在于大多数功能库中,如lodash和ramda都有实现。
使用新的管道运算符,可以不使用第三方库并按如下所示编写上述内容:
let result = "hello" |> doubleSay |> capitalize |> exclaim; result //=> "Hello, hello!"`
这个提案目的是使链式调用函数更具可读性,在未来结合函数部分应用也可以很好的工作,类似下面这种使用方式:
let result = 1 |> (_ => Math.max(0, _)); result //=> 1 let result = -5 |> (_ => Math.max(0, _)); result //=> 0
编写如下测试用例:
import test from 'ava'; function doubleSay (str) { return str + ", " + str; } function capitalize (str) { return str[0].toUpperCase() + str.substring(1); } function exclaim (str) { return str + '!'; } test('Simple pipeline usage', (t) => { let result = "hello" |> doubleSay |> capitalize |> exclaim; t.is(result, 'Hello, hello!'); }); test('Partial application pipeline', (t) => { let result = -5 |> (_ => Math.max(0, _)); t.is(result, 0); }); test('Async pipeline', async (t) => { const asyncAdd = (number) => Promise.resolve(number + 5); const subtractOne = (num1) => num1 - 1; const result = 10 |> asyncAdd |> (async (num) => subtractOne(await num)); t.is(await result, 14); });
需要注意,一旦将async函数添加到管道,必须await该返回值,因为此时返回值是promise。有一提案开始支持|> await asyncFunction,但尚未实现。
最后,既然你已经看到了这些提案的实际应用,我希望你能够尝试一下这些提案!
以上就是小编今天为大家分享的关于JavaScript的 新特性的文章,希望本篇文章能够对正在从事Web前端工作的小伙伴们有所帮助。想要了解更多Web相关知识记得关注达内Web培训官网哦~
英文:Justin Fuller 作者:川木。
*声明:内容与图片均来源于网络(部分内容有修改),版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved