当前位置: 首页 > Web前端 > HTML

(含Vue3学习资料群)JavaScript:ECMAScript2020新特性

时间:2023-04-02 22:05:19 HTML

有兴趣的可以进微信群。过期了可以在下方留言,或者关注我的微信公众号《人生代码》《人生代码》《人生代码》,回复群,加我微信,拉你进群,重要的事情说三遍。JavaScript即将推出令人兴奋的新功能!尽管新的ECMAScript2020(ES2020)语言规范已经在6月获得最终批准,但您今天就可以开始尝试了!处理模块一些重要的创新涉及模块。其中,开发者要求已久的一个特性就是动态导入。但是,让我们按顺序查看详细信息。动态导入当前的模块导入机制是基于这样的静态声明:import*asMyModulefrom"./my-module.js";该语句有两个约束:导入模块中的所有代码都在加载时针对当前模块进行评估模块的说明符(上例中的“./my-module.js”)是一个字符串常量,您不能更改它在运行时。这些约束阻止了模块的条件加载或按需加载。同样,在加载时评估每个依赖模块会影响应用程序的性能。新的import()语句允许您动态导入模块,从而解决了这些问题。此语句接受模块说明符作为参数并返回承诺。同样,模块说明符可以是任何返回字符串的表达式。这是个好消息,因为我们现在可以在运行时加载JavaScript模块,如以下示例所示:constbaseModulePath="./modules";constbtnBooks=document.getElementById("btnBooks");letbookList=[];btnBooks。addEventListener("click",asynce=>{constbookModule=awaitimport(`${baseModulePath}/books.js`);bookList=bookModule.loadList();});这段代码显示books.js进入了用户列表如何在点击btnBooks按钮时正确加载模块。加载模块后,单击事件处理程序将使用模块导出的loadList()函数。请注意要导入的模块是如何通过字符串插值指定的。导入元数据import.meta对象为当前模块提供元数据。JavaScript引擎创建了它,它当前可用的属性是url。此属性的值是从中加载模块的URL,包括任何查询参数或哈希值。例如,您可以使用import.meta.url属性为存储在与当前模块相同的文件夹中的data.json文件构建URL。下面的代码实现了这个结果:constdataUrl=newURL("data.json",import.meta.url);在这种情况下,import.meta.url为URL类提供了data.json文件的基本URL。ECMAScript2015规范引入的新导出语法导入声明为您提供了多种形式的模块导入。以下是一些示例:从“./my-module.js”导入{value};从“./my-module.js”导入*;在某些情况下,您可能需要导出从另一个模块导入的对象。方便的导出语法可能会帮助你,像这样:export{value}from"./my-module.js";从“./my-module.js”导出*;从开发人员的经验来看,导入和导出语句之间的这种对称性是得心应手的。但是,在这些新规范之前不支持特定情况:import*asMyModulefrom"./my-module.js";要导出MyModule命名空间,应使用两个语句:import*asMyModulefrom"./my-module.js";export{MyModule};现在,您可以使用这样的单个语句获得相同的结果:export*asMyModulefrom"./my-module.js";此添加可简化您的代码并使导入和导出语句之间对称。数据类型和对象新的ES2020规范引入了新的数据类型、标准化的全局对象以及一些简化开发人员生活的方法。让我们来看看。BigInt和任意精度整数如您所知,JavaScript只有一种数据类型:数字。这种基本类型允许您表示64位浮点数。当然,它也表示整数,但最大可表示的值为253,对应Number.MAX_SAFE_INTEGER常量。在不深入整数表示的内部细节的情况下,有些情况下您可能需要更高的精度。考虑以下情况:与提供64位整数数据(例如GUID、帐号或对象ID)的其他系统交互需要超过64位的复杂数学计算的结果。第一种情况的解决方案是将数据表示为字符串。当然,此解决方法不适用于第二种情况。新的BigInt数据类型旨在解决这些问题。您可以通过简单地将字母n附加到数字来表示BigInt文字,如以下示例所示:constaBigInteger=98765432123456789n;您还可以像使用BigInt()构造函数一样使用Number()构造函数:constaBigInteger=BigInt("98765432123456789");typeof现在,运算符将“bigint”应用于一串BigInt值返回:typeofaBigInteger//输出:“bigint”请记住,Number和BigInt是不同的类型,因此不能混用。例如,尝试将Number值添加到BigInt值会引发TypeError异常,如下图所示:您必须使用构造函数显式地将Number值转换为Value。用于正则表达式的matchAll()方法的BigIntBigInt()您可以通过多种方式获取给定正则表达式的所有匹配项。这是其中一种方法,但您可以使用其他方法:constregExp=/page(\d+)/g;consttext='textpage1texttextpage2';letmatches;while((matches=regExp.exec(text))!==null){console.log(matches);}此代码遍历匹配变量文本中的所有页面x实例。在每次迭代中,exec()方法对输入字符串运行,您会得到如下结果:["page1","1",index:5,input:"textpage1texttextpage2",groups:undefined]["page2","2",index:22,input:"textpage1texttextpage2",groups:undefined]String对象的matchAll()方法,可以得到相同的结果,但是在更紧凑的时尚,更好的性能。以下示例使用这种新方法重写了以前的代码:constregExp=/page(\d+)/g;consttext='textpage1texttextpage2';letmatches=[...text.matchAll(regExp)];for(constmatchofmatches){console.log(match);}matchAll()方法返回一个迭代器。前面的示例使用展开运算符将迭代器的结果收集到数组中。全局对象访问全局对象需要不同的语法,具体取决于JavaScript环境。例如,在浏览器中,全局对象是window,但您不能在WebWorker中使用它。在这种情况下,您需要使用self.另外,在Node.js中,全局对象是全局的。当编写旨在在不同环境中运行的代码时,这会导致问题。您可能使用过this关键字,但它在严格模式下运行的模块和函数中未定义。globalThis对象提供了一种跨不同JavaScript环境访问全局对象的标准方法。所以现在您可以以一致的方式编写代码,而无需检查当前的运行环境。但请记住尽量减少全局变量的使用,因为这被认为是不好的编程习惯。Promise.allSettled()方法目前,JavaScript有两种组合promise的方法:Promise.all()和Promise.race()。这两种方法都将一组承诺作为参数。下面是一个使用Promise.all()的例子:constpromises=[fetch("/users"),fetch("/roles")];constallResults=awaitPromise.all(promises);Promise.all()whenall当两个承诺都得到满足时返回一个承诺。如果至少有一个承诺被拒绝,则返回的承诺将被拒绝。最终的promise因与第一个被拒绝的promise相同的原因而被拒绝。当至少一个promise被拒绝时,此行为不会为您提供一种直接获取所有promise结果的方法。例如,在上面的代码中,如果fetch("/users")失败并且相应的promise被拒绝,您没有一个简单的方法来知道promisefetch("/roles")是被兑现还是被拒绝。要获得此信息,您必须编写一些额外的代码。新的Promise.allSettled()组合器将等待所有承诺得到履行,而不管它们的结果如何。所以下面的代码让你知道每个承诺的结果:constpromises=[fetch("/users"),fetch("/roles")];constallResults=awaitPromise.allSettled(promises);consterrors=results.filter(p=>p.status==='rejected').map(p=>p.reason);特别是,这段代码让您知道为什么每个被拒绝的承诺都失败了。新运算符几个新的运算符将使编写和阅读非常常见的操作的代码更加容易。猜猜哪一个?您见过多少次空合并运算符并使用了以下表达式?常量大小=settings.size||42;||当您尝试分配的默认值是null或undefined时,运算符通常用于分配默认值undefined。但是,这种方法可能会导致一些潜在的意外结果。比如上例中的size常量42,当settings.size的值为0时,也会被赋值为0。但是,当settings.size的值为""或false时,也会指定默认值。为了克服这些潜在的问题,您现在可以使用void合并运算符(??)。之前的代码如下:constsize=settings.size??42;这允许仅当值为or42时才将默认值分配给大小常量。settings.sizenullundefined可选链接考虑以下示例:consttxtName=document.getElementById("txtName");常量名称=txtName?txtName.value:未定义;您的txtName将从当前HTML文档中获取带有其标识符的文本框。但是,如果文档中不存在HTML元素,则txtName常量将为空。因此,在访问其value属性之前,必须确保txtName不为null或undefined。可选的链接运算符(?.)允许您拥有更紧凑和可读的代码,如下所示:consttxtName=document.getElementById("txtName");constname=txtName?.value;与前面的示例相同同样,如果txtName不为空或未定义,名称常量的值将为txtName.value;;否则未定义。这个运算符的优点在像这样的复杂表达式中更能体现出来:constcustomerCity=invoice?.customer?.address?.city;您还可以将可选的链接运算符应用于动态属性,如以下示例所示:constuserName=user?.["name"];此外,它适用于函数或方法调用:constfullName=user.getFullName?.();在这种情况下,如果getFullName()方法存在,它将被执行。否则,表达式返回未定义。使用新功能在整篇文章中,您已经大致了解了ES2020的新功能,并且您可能想知道何时可以使用它们。据caniuse.com报道,所有最近的主流浏览器(除了InternetExplorer)都已经支持ECMAScript2020带来的新特性。但是,在撰写本文时,Safari不支持新的BigInt数据类型和matchAll()方法。在最新版本的Node.js中,支持所有功能,包括动态导入的支持ECMAScript的模块。最后,Babel和TypeScript等最流行的编译器的最新版本也让您可以使用最新的ES2020功能。方面:使用JavaScript的Auth0身份验证在Auth0,我们大量使用全栈JavaScript来帮助客户管理用户身份,包括密码重置、创建、配置、阻止和删除用户。因此,不用说,在JavaScriptWeb应用程序上使用我们的身份管理平台是小菜一碟。Auth0提供免费套餐以开始使用现代身份验证。检查一下,或在这里注册一个免费的Auth0帐户!然后,转到Auth0仪表板的应用程序部分并单击创建应用程序。在出现的对话框中,为应用程序设置名称,并选择“单页Web应用程序”作为应用程序类型:创建应用程序后,单击“设置”并记下域和客户端ID。此外,将“允许的回调URL”和“允许的注销URL”字段设置为将处理Auth0的登录和注销响应的页面的URL。在当前示例中,页面的URL将包含您要编写的代码(例如http://localhost:8080)。现在,在您的JavaScript项目中,按如下方式安装auth0-spa-js库:npminstall@auth0/auth0-spa-js然后,在您的JavaScript应用程序中执行以下操作:';letauth0Client;asyncfunctioncreateClient(){returnawaitcreateAuth0Client({domain:'YOUR_DOMAIN',client_id:'YOUR_CLIENT_ID'});}asyncfunctionlogin(){awaitauth0Client.loginWithRedirect();}functionlogout(){auth0Client.logout();}asyncfunctionhandleRedirectCallback(){constisAuthenticated=awaitauth0Client.isAuthenticated();如果(!isAuthenticated){constquery=window.location.search;如果(query.includes("code=")&&query.includes("state=")){awaitauth0Client.handleRedirectCallback();window.history.replaceState({},document.title,"/");}}awaitupdateUI();}asyncfunctionupdateUI(){constisAuthenticated=awaitauth0Client.isAuthenticated();constbtnLogin=document.getElementById("btn-login");常量btnLogout=document.getElementById("btn-注销");btnLogin.addEventListener("点击",登录);btnLogout.addEventListener("点击",注销);btnLogin.style.display=(isAuthenticated?"none":"block");btnLogout.style.display=(isAuthenticated?"block":"none");if(isAuthenticated){constusername=document.getElementById("用户名");constuser=awaitauth0Client.getUser();用户名.innerText=用户。姓名;}}window.addEventListener("load",async()=>{auth0Client=awaitcreateClient();awaithandleRedirectCallback()});将YOUR_DOMAIN和YOUR_CLIENT_ID占位符替换为您在Auth0仪表板中找到的域和客户端ID的实际值然后,使用以下标记创建UI:

Welcome/p>登录退出您的应用已准备好使用Auth0进行身份验证!查看Auth0SPASDK文档以了解有关使用JavaScript和Auth0进行身份验证和授权的更多信息。