本文是Microsoft的Web开发系列的一部分。 感谢您支持使SitePoint成为可能的合作伙伴。
ECMAScript 6或ES6是JavaScript的发展,并且是未来。 这是我们一直在等待的Web技术创新。 它充满了我们一直渴望的强大功能,最终使我们能够以可扩展且易于维护的方式为网络构建大型应用程序。 它使成千上万来自Java或C#或其他“高级”语言的开发人员能够最终编写JavaScript,并将迫切需要的所有经验带到市场中,这些都需要组织和指导。
那是销售的推销,公平地说,很多是真的。 但是,对于需要在网络上修复的内容,它也做出了很多假设。 在不控制其执行环境的情况下,发展一种像JavaScript这样无处不在的语言确实存在一个问题。Web是一个分布式平台。 相比于您可以带回商店,锁止,升级和再次驶出的车辆,要在不断行驶的车辆上更换车轮要困难得多。
JavaScript似乎再也无法削减了
我们应该说,JavaScript的宽松架构一直是来自其他语言的程序员的困惑之源。 尤其是缺少类和原型继承对于很多人来说都是不可行的。 感觉违反直觉,并不代表学校正在教授有关计算的知识。 更糟的是,我们有一个漂亮但令人困惑的闭包构造,并且缺少常量和类型安全性。 所有这些都意味着JavaScript因其糟糕的架构以及不被大型代码库所信任而享誉盛名。 尽管如此,它还是成功地发展成为当今软件开发中最常用的语言之一-很大程度上要归功于网络的兴起。
ES6和以下语言的版本旨在消除这些麻烦,并使JavaScript成为一种更好,更可靠和更高效的语言。
公平地说,这并不是什么新鲜事。 过去,我们有几种基于JavaScript的语言,并试图解决这些问题。 TypeScript , Dart , CoffeeScript甚至Flash的ActionScript都试图解决同一问题。 不同之处在于,它们都需要某种转换或容器才能显示在浏览器中。 ES6(现已定稿)旨在供浏览器使用,并像使用指向它的脚本元素的JavaScript一样运行。 ES6具有许多令人印象深刻的功能:
- Arrow函数是匿名函数的简写形式。
- 使用let而不是var的 块级作用域使变量作用于块(if,for,while等)
- 类来封装和扩展代码。
- 常量使用const关键字。
- 像foo(bar = 3,baz = 2)这样的函数的默认参数
- 进行解构以将值从数组或对象分配给变量。
- 发电机创造使用功能*, 产量关键字的迭代器。
- Map ,一个Dictionary类型的对象,可用于存储键/值对。 设置为收集对象以存储数据值列表。
- 模块是组织和加载代码的一种方式。
- 异步操作的承诺避免回调地狱
- 休息参数,而不是使用参数来访问函数参数。
- 模板字符串以建立包括多行字符串的字符串值。
考虑到这些天我们正在使用JavaScript做什么,这似乎是一个真正的需求。 游戏,应用程序开发甚至服务器端开发都可以使用JavaScript进行。 在每种环境下,我们都有开发人员习惯于不同的工具和方法。 过去狂野的西部网络发展似乎与今天的性能和维护需求适得其反。 这使我想起了从DHTML转到DOM Scripting的年代。 订单,我们需要订单和可靠性。
与此不同的是,当前ES6尚未准备好在Web上部署。 那不是语言的错,而是网络的本质。 我们不能也不应规定人们使用什么上网。 但是在当前不同的浏览器中对ES6的支持并不令人鼓舞。
更大的问题是ES6在JavaScript历史上首次打破了与设备和浏览器无关的Web观念。
用新语法破坏网络
ES6的问题并不在于它对语言的作用– JavaScript始终通过新方法和API进行了扩展。 为了安全地使用它们,我们要做的只是在应用之前测试当前的浏览器或环境是否了解此功能。 这称为渐进式增强,这意味着我们永远不会提供破碎的体验。
当在调用某个方法之前测试它是否存在时,您是安全的。 就像在跳入之前检查河流是否足够深是一个好主意。 ES6的问题在于,由于向JavaScript引入了许多语法更改,而不仅仅是新的方法和对象,它破坏了向后兼容性。
这不应该成为问题,但是与用于在网络上构建“事物”的所有其他语言不同(有意识地避开了网站与应用的争论),JavaScript不是容错的。
以下HTML对浏览器而言不是问题:
<p><span>Nesting</p></span>
在内部,此问题已得到解决,浏览器继续采用自己的方式呈现页面的其余部分:
Firefox开发人员工具显示HTML5解析器如何修复错误嵌套的HTML
这种容错性是HTML5的主要思想之一。 HTML5解析器非常宽容,因为我们知道开发人员会犯错误,而我们的用户也不会因此而受苦。 带有单个错误的XHTML文档将无法呈现。 这还不够好–我们需要一个更坚固的网络,因为最终用户的体验胜过其他一切。 这甚至被定义为HTML的设计原则, 即选区的优先级 :
在发生冲突的情况下,请考虑用户胜过作者,胜过实现者,胜过说明符,而不是理论纯度。 换句话说,对用户的成本或困难应比对作者的成本更为重视; 反过来,这应该比实施者的成本更受重视; 对于规范本身的作者而言,这应该比对成本的重视更大,而对于仅出于理论原因而提出变更的建议,则应当比对成本更高的重视。 当然,最好一次使多个选区更好。
CSS解析器对代码的态度相同。 例如,应用了此CSS的文档中的段落将是浅橙色。
p {color: microsoftblue;}
p {color: peachpuff;}
p {colour: powderblue;}
“ peachpuff”是CSS颜色的有效名称,而“ microsoftblue”则不是。 虽然“ powderblue”也是一种有效的颜色,但是在CSS中,在语法上正确拼写的“ color”必须是“ color”,这就是为什么它没有被应用的原因。 本质上,跳过了CSS解析器无法处理的任何代码行。
这种容错在JavaScript中不起作用,这就是为什么它是Web堆栈中最脆弱的部分。 导致JavaScript错误的任何问题都意味着不会执行整个脚本-浏览器中没有容忍度。
当人们讨论逐步增强Web的需求时,这常常被忘记。 与禁用JavaScript的最终用户无关,它们只是一小部分。 这是在执行JavaScript之前以及浏览器最终尝试运行它时所有可能出错的事情。 Stuart Langridge维护着一个有趣的决策树,它告诉您从请求脚本到执行脚本可能出错的所有内容。
ES6引入了许多对JavaScript语法的更改。 尽管ES6兼容的浏览器或预处理器的以下代码没有问题,但对于非ES6浏览器,这只是语法错误。
function showperson(ismember = 0, hasphoto = 0, ...moar) {
/* … */
}
这给我们带来了一个大问题。 除非我们将自身限制在少数已经支持ES6的浏览器中,否则不可能使用ES6。 Microsoft Edge ,Firefox,Chrome和iOS Safari均具有良好的ES6子集。 但是,并非所有这些浏览器都是我们的用户所拥有的,并且我们不能假设人们一直在升级。 令人遗憾的是,那里有很多硬件,这些软件都带有不可升级的操作系统,并且其中装有过时的浏览器。
功能检测语法支持?
Kyle Simpson的 Featuretests.io是解决此问题的一种非常有趣的方法。 这是一个非常小的JavaScript库,可让您测试ES6功能,因此仅在浏览器支持时以及在它们支持时才加载ES6脚本。 可以这么说,在语法层面上逐步增强。
使用此库,您可以测试您拥有的浏览器并查看其支持的浏览器。 现在快速检查一下我的机器就会显示以下内容:
我不是要在这里比较浏览器-看到时间变化有多快,这是浪费时间。 我想表明的是,当涉及到浏览器中对ES6的支持时,它们之间存在很多差异。 这使功能测试不方便,因为只有在测试所有要使用的东西时,它才是安全的。 如果仅测试一个,则假定对其他功能的支持是滑坡。
如果您一直坚持到底,并想对要使用的每个功能进行测试,则代码不会中断。 但是,它很容易变成过度杀伤力。 对于许多开发人员而言,ES6的重点不是使用零碎的功能,而是从一开始就将整个应用程序编写在ES6中。
没什么新鲜的。 当HTML5和CSS3只是一个炒作而我们迫不及待地使用它时,我们得到了很多“这个很酷的东西仅在Safari中有效”或“您需要使用Chrome浏览器才能看到此站点”的很多信息。功能仍在不断变化。 这些产品仍在网络上,基本上不需要维护,浏览器需要在代码库中包含很多内容,以免破坏网络。 我们想要太多,太快了,之后我们没有清理。
为了使开发人员能够使用Modernizr自动检测所有内容,我们付出了很多努力。 对于旧版浏览器支持,这仍然是一个很好的主意,但是在定义更明确的环境中,开发人员发现这是不必要的开销。 取而代之的是,我们开始设置支持基准,并且仅向实现这一目标的那些浏览器提供脚本功能和高级样式。 英国广播公司(BBC)的开发者在三年前称其为“ 切芥末 ”,他们的基准是以下几项检查:
if ('querySelector' in document &&
'localStorage' in window &&
'addEventListener' in window) {
// bootstrap the javascript application
}
也许这也是我们在ES6工作中可以想到的东西? 定义一些可以检查并从那里继续前进的网闸功能?
如果您不希望依赖浏览器支持,而只想使用ES6,那么您将需要使用一些可转换代码的工具。 这可能是自己的语言,如TypeScript或所谓的Transpiler(因为它将ES6转换并编译为JavaScript)。
转为救援?
如今,关于JavaScript的好处是它摆脱了浏览器的限制,并且可以在服务器端使用。 node.js使用Chrome的V8引擎作为独立的二进制文件,现在还可以使用Microsoft的Chakra JS引擎 。 这使我们能够使用任何JavaScript转换工具来获取ES6代码,并将其转换为可在任何浏览器中运行的良好的旧JavaScript。 如果您已经在使用Grunt或Gulp进行任务管理,那么这可能只是部署之前要运行的另一项任务。
有一些选择。 最著名的编译器是Traceur ,它们起源于Google和Babel ,最初称为6到5,但是随着ECMAScript的发展,即使我们尝试实现它,也需要一个更通用的名称。
目前,转译似乎是在实际项目中使用ES6的最安全方法,而不必担心跨环境的支持差异。 它也与习惯于更严格和基于类的语言的开发人员的工作流程紧密地联系在一起。 但是,自省之后,存在一些怪异的缺点:
- 首先,在大多数情况下,编译根本不进行任何功能检测-ES6代码已完全转换为ES5(或者在某些情况下甚至可以转换为ES3,如果您想这样做)。 这意味着本机支持ES6的浏览器将永远无法获取代码。 它使浏览器中的实现有点多余,并且-更糟的是-它不允许在浏览器中测试ES6实现的性能和有效性。
- 传统上,网络是视图源。 过去,这就是我们许多人学习如何为其编写代码的方式。 在错误控制台中看到有问题后,我们查看了源代码并发现了其他人使用的代码,并且调试过程也在做同样的事情。 如今,我们拥有用于开发人员的工具,具有更多高级功能。 但是,如果我们编译代码,就永远不会编写要执行的代码。 我们在浏览器中调试的代码是编译器创建的,编译器针对性能进行了优化,而不是为了提高可读性。 为了调试我们的代码,我们需要找到一种方法来将生成的代码与编写的代码连接起来。 为此,我们使用源映射 。 这也适用于Sass或更少生成的CSS。
- 从其他代码生成代码可能会导致大量文件。 当最终结果意味着用户必须下载兆字节的JavaScript才能获得更轻量级的接口时,我们编写的原始代码紧凑,干净,结构化不一定重要。
表现如何?
每当我们向浏览器引入新功能时,就会出现一个问题,那就是我们使处理速度加快还是减慢了速度。 我们只是不知道,直到我们收集了足够的数据来找出优化的地方。 在ES6的情况下,如果我们对代码进行转译,则无法真正进行数据收集。 目前, 凯文·德克尔(Kevin Decker)的速度报告显示,本机在浏览器中ES6的性能看起来并不太令人鼓舞。
该报告显示了ES6功能相对于每秒ES5基准操作的性能。 所有不是深绿色的东西都比JavaScript慢。 并非深绿色的所有内容要么较慢,要么与ES5性能相同。 这意味着只有传播算子 , Promises , Maps和Sets可以带来性能上的好处。
ES6很重要,需要我们注意
现在,就整个Web开发而言,ES6处于一个怪异的境地。 它是一个标准,得到了很好的支持(例如,Web组件除外),但是它也破坏了向后兼容性。 除了要赞扬它所做的所有伟大事情,并没有显示可能对您有用的示例之外,我想邀请您参加有关ES6的讨论。 这就是为什么我想在这里结束时提几个问题供您思考,我们很乐意在评论中听到您的意见。
如果我们的主要目的是通过编码工作来创建Web内容,那么我们需要问自己几个问题:
- 我们是否让开发人员的便利性胜过最终用户体验? 是否比在特定环境下交付性能最佳的解决方案更重要,交付速度更快,更重要?
- 在我们更轻松,更快速,更可维护的情况下,构建能够期望更多最终用户环境的大型应用程序是否可以?
- 能够更轻松地更改应用程序并以更明确的方式扩展应用程序来弥补对用户的锁定吗?
- 现在是时候在沙子上划一条线,使JavaScript更安全,更容易扩展了吗?
- 网络持续向后兼容的概念存在缺陷吗? 我们是通过迎合最低公分制来阻止自己吗?
- ES6的新功能真的有好处吗?还是我们只是试图追赶并重复其他环境所做的事情? 看到整个软件可能损坏 ,这真的是我们能做的最好的事情吗?
- 这些更改的好处值得使用它们的努力吗? 进入网络的新开发人员是否应该使用编译器,预处理器和任务运行程序来入门?
- 当编译器创建ES5时,我们如何帮助浏览器更好地支持ES6?
- 是使用JavaScript的子集(如TypeScript)更好的选择吗?
- 从浏览器获取的代码中提取我们编写的代码是正确的方向吗? 视图源已经失去了它的用处吗?
- ES6是否是另一种在Web上工作的方式–就像使用emscripten is或Flash was将字节码转换为JavaScript一样? 对于Web开发人员来说,预编译步骤似乎很奇怪,但是Java的人对此完全可以接受。 换句话说,ES6是否不适合所有人,但我们会尽力做到这一点?
在接下来的几个月中,围绕ES6将会令人兴奋,它的本质意味着将有相当长的一段时间进行持续的讨论和讨论。 它对不喜欢JavaScript的灵活性和随机性的人非常有吸引力。 它会使那些坚定地使用JavaScript的人感到困惑,并且感到很多开销,而没有太多直接的好处。 进化总是伴随着成长的痛苦。 是时候说出来,尝试一下对您有用的了。
使用JavaScript进行更多操作
本文是Microsoft技术传播者开发的Web开发系列文章的一部分,内容涉及实用的JavaScript学习,开源项目以及互操作性最佳实践,包括Microsoft Edge浏览器和新的EdgeHTML呈现引擎 。
我们鼓励您使用dev.modern.IE上的免费工具跨浏览器和设备进行测试,包括Microsoft Edge(Windows 10的默认浏览器):
- 扫描您的站点以查找过期的库,布局问题和可访问性
- 在Mac,Linux和Windows上使用虚拟机
- 在您自己的设备上远程测试Microsoft Edge
- GitHub上的编码实验室:跨浏览器测试和最佳实践
我们的工程师和宣传人员在Microsoft Edge和Web平台上进行了深入的技术学习:
- Microsoft Edge Web Summit 2015 (新浏览器,受支持的新网络平台标准以及来自JavaScript社区的嘉宾演讲者会期待什么)
- 哇,我可以在Mac和Linux上测试Edge和IE! (来自Rey Bango)
- 在不中断网络的情况下推进JavaScript (摘自Christian Heilmann)
- 使Web正常工作的Edge渲染引擎 (来自Jacob Rossi)
- 使用WebGL释放3D渲染 (来自David Catuhe,包括vorlon.JS和babylonJS项目)
- 托管的Web应用程序和Web平台创新 (来自Kevin Hill和Kiril Seksenov,包括歧管 .JS项目)