一文道尽JavaScript 20年的发展史
作者介绍:Andrew Montalenti是Parse.ly的CTO, 一个长期的Python爱好者,以及初创公司和其他项目的创始人。
原文链接:https://amontalenti.com/2019/08/10/javascript-the-modern-parts
在过去的几个月里,我通过Node 8,Webpack 4和Babel 7提供的本地工具学到了很多关于现代JavaScript和CSS开发的知识。作为其中的一部分,我正在进行第二次“重新认识JavaScript”。 我在1998年首次学习JS。然后在2008年重新开始,在“The Good Parts”年代,Firebug,jQuery,IE6兼容性,以及最终成熟的Node生态系统时代。 在那个时代,我在网上编写了一个最广泛部署的一个JavaScript前端系统。
现在我正在ECMAScript(ES6 / ES2017)时代重新学习它,预编译,第三方库和模块化的正式支持,以及PWA,代码分割和WebWorkers/ServiceWorkers等移动网络性能。 令人惊喜的是,通过ECMAScript标准和Babel,JS已经发展成为一种非常好的编程语言,所有事情都被考虑在内。
为了巩固所有这些东西,我使用webpack/babel为一个简单的Python/Flask Web应用程序构建所有静态资产,最终部署成一个数百页的静态站点。
一个周末,我将所有内容从Flask-Assets移植到webpack,并使用ES2017功能,以及探索Sass CSS预处理器和一些D3.js示例。让我们从头开始!
1998年的JavaScript
我在1998年首次学习JavaScript。很难相信这是20年以前了。这篇文章将描述自那以来的二十年 - 涵盖了1998年,2008年和2018年的JavaScript。本文的重点将放在“现代”JavaScript上,根据我在2018/2019的理解,特别是非JavaScript程序员应该知道语言及其相关的工具和运行时是如何发展的。
如果你是那种思考的程序员,“我用Python/Java/Ruby/C编写代码,因此我没有使用JavaScript,也不需要了解它”,你错了,我会描述原因。顺便说一句,你在1998年是对的,你可以在2008年没有它,而你在2018年就错了。
此外,如果你是一个程序员,他认为“JavaScript是一个变化很快的技术,我宁愿避免,因为它缺乏基本的基础设施,我们认为在'真正'的编程语言中这些是理所当然的”,那么你也错了。我将能够向你展示在2018年“不认真对待JavaScript”就像2008年代程序员不认真对待Python或Ruby一样严重无知。
JavaScript不仅是一种语言,而且已经并将继续在几个重要领域接管世界。要成为一名认真的程序员,您必须了解JavaScript的现代和好的部分以及其他一些服务器端语言,如Python,Ruby,Go,Elixir,Clojure,Java等。但是,尽管您可以为使用不同的一种后端语言,但您无法避免使用JavaScript:它在各种Web部署方案中都很普遍。而且,开发人员工具已经完全满足您的期望。
浏览器大战中的JavaScript
浏览器是一个苛刻的环境,以发展为目标; 不仅互联网采用率低,而且互联网连接不仅缓慢,而且浏览器大战 - 主要是在网景和微软之间 - 引发了很多混乱。
Netscape Navigator 4于1997年发布,Internet Explorer 5于1998年发布。网络仍在尝试理解HTML和CSS; 毕竟,CSS1仅在一年前发布。
在这种环境下,当时最权威的网络开发书籍是“JavaScript:The Definitive Guide”,超过500页。 请注意,在1998年,使用最广泛的编程语言是C,C ++和Java,以及Microsoft Visual Basic for Windows。因此,关于“编程是什么”的主题主要围绕着这些语言。
从这个意义上讲,JavaScript非常不同。它没有编译器,没有调试器(至少不是很好的调试器), 没有办法“运行JavaScript程序”,除了在浏览器中编写脚本,并查看它们是否运行。 JavaScript的开发工具仍然是原始的或不存在的。JS当然没有太多的开源社区; 要弄清楚如何做事,你通常会在其他人的网站上“查看源码”。 此外,Web开发人员编程社区中的大部分讨论都是JavaScript中兼容性和安全性的噩梦。
不仅可以跨浏览器实现不同的实现,还可以通过多种方式直接依赖JavaScript来破坏Web应用程序的安全性。那个时代的常见安全漏洞是使用JavaScript验证表单,但仍允许将无效(和不安全)值传递给服务器。或者,要对系统进行密码保护,但检查JavaScript代码本身可能会破坏对该系统的访问。结合缺乏适当的开发环境,“真正的网络程序员”使用JavaScript只不过是最后的手段 - 一种将一些客户端代码和逻辑注入到服务器端的服务器端的方式。我记得当时JavaScript最常见的用例之一只是在悬停时更改图像,作为风格效果,或在复杂的多选项卡表单上实现基本的悬停菜单。目前,这些任务可以通过纯CSS实现,但是,当时,JavaScript DOM操作是您唯一的选择。
2008年的JavaScript
快进10年来到2008年,Douglas Crockford发布了“JavaScript:The Good Parts”这本书。 通过使用语言子集方法,Crockford指出,JavaScript不仅不是一种糟糕的语言,它实际上是一种优秀的语言,设计精良,具有某些关键功能,使其与竞争对手相比更加突出。
大约在这个时候,一些JavaScript库变得流行,特别是jQuery,Prototype,YUI和Dojo。 这些库试图为JavaScript提供它缺少的东西:跨浏览器兼容性和编程模型,用于对浏览器内的页面进行动态操作,特别是对于新出现的JavaScript编程模型-AJAX。 这是富互联网应用程序,“动态”Web应用程序,单页应用程序等趋势的开始。
JavaScript工具集的飞跃
JavaScript的开发工具也取得了一些重要的飞跃。 2006年,Firefox团队发布了Firebug,这是Firefox的JavaScript和DOM调试器,后来Firefox成为世界上最受欢迎的Web浏览器之一,也是开源的。两年后,谷歌将首次发布谷歌Chrome,它捆绑了一些开发人员工具。大约在Chrome发布的同时,谷歌还发布了V8,这是嵌入Chrome内部的JavaScript引擎。这标志着世界第一次看到JavaScript语言的完整,高性能的开源实现,并没有完全与浏览器绑定。 Firefox的JS引擎SpiderMonkey是其源代码树的一部分,但不一定是在Firefox浏览器的上下文之外进行模块化和使用。
我记得除了Crockford确定JavaScript的优点之外的工作,除了新的(和更好的)开发人员工具之外,Mozilla网站上的一篇特定文章帮助我重新欣赏了这种语言,并抛弃了我1998年的概念。那篇文章被称为“A Reintroduction to JavaScript”。它展示了JavaScript实际上是一种真正的编程语言。它的标准库有点不足,因此你必须依赖框架(比如jQuery)来为你提供一些工具,以及除此之外的微型库。
读完那篇文章一年后,我写了一篇关于JavaScript的文章,它被称为“Real, Functional Programs with JavaScript”。 它描述了JavaScript是一种非常令人惊讶的功能语言,它不是Java 8或Python 2.7。 而且只需要专注于理解功能核心,就可以编写出非常好的程序。 我最近将这篇文章转换成了一组教学幻灯片,名称为“Lambda JavaScript”,我现在用它来向新设计师/开发人员讲授第一原理语言。
好吧,让我们回到历史。Chrome发布仅一年后,在2009年,我们看到了NodeJS的第一个版本,它采用V8 JavaScript引擎并将其嵌入到服务器端环境中,可用于在REPL上试验JavaScript,以便编写 脚本,甚至可以依赖高性能事件循环特性来实现HTTP服务器。
人们开始尝试用JavaScript编写的命令行工具,以及用JavaScript编写的Web框架。正是在这一点上,JavaScript社区的发展速度加快了。 2010年,npm(节点包管理器)发布了,它及其软件包注册表迅速发展,代表了完整的JavaScript开源社区兴起。在接下来的几年里,Mozilla,谷歌,苹果和微软的浏览器厂商参与了“JavaScript引擎战争”,每个人都将SpiderMonkey,V8,Nitro和Chakra发展到了一个新的高度。
同时,NodeJS和V8成为从命令行在开发人员的机器上运行的“标准”JS引擎。虽然开发人员仍然不得不兼容旧的“ECMAScript 3”浏览器(例如IE6),因此必须编写受限制的JavaScript代码,但Mozilla,Google和Apple的“年轻”(自动更新)浏览器对ECMAScript 5和后续ES版本的支持,移动网络浏览成为主流,从而使Chrome和Safari在市场份额中占据主导地位,特别是在智能手机上。
我记得在2012年,我在当地的一个技术会议上做了题为“用JavaScript编写真正的程序!?”的演讲。 “!?”标点符号是故意的。那是我在一个充满开发人员的房间里记得的一个时代的变化:也就是说,“用JavaScript编写真正的程序......实际上可能!?”将这些幻灯片作为历史遗迹进行审查是很有趣的。我在讲座的前半部分让观众相信JavaScript的功能核心实际上非常好。然后我花了下半部分说服NodeJS可能......它可能......创建一个开发人员工具生态系统和JavaScript的标准库。 Comet vs Ajax之类的东西也有一些有趣的“绕行”幻灯片,这个辩论实际上并不多(但提醒科技的流行趋势很好)。
几年前,在Web 2.0,云端和移动设备的所有噪音中,我们终于来到了移动时代,2015年移动流量超过了桌面流量,我们也看到了几个桌面操作系统迁移到了大多数常青树模型,例如Windows 10,Mac OS X和ChromeOS。因此,早在2015年 - 但肯定到2018年 - JavaScript成为部署最广泛且性能最高的编程语言,几乎在世界上所有台式机和移动计算机上都具有“内置支持”。
换句话说,如果您希望您的代码在2015年左右“一次编写,随处运行”,您最好的选择是JavaScript。那么,今天更是如此。广泛分发代码的可靠选择仍然是JavaScript。正如克罗克福德在2008年预测的那样:“幸运比聪明更好。”
2018-2019年的JavaScript
在2018-2019,关于JavaScript社区的一些事情发生了变化。开发工具不再是初出茅庐的,而是成熟的。所有Safari,Firefox和Chrome浏览器都有内置的开发工具(Firebug项目大多已被弃用)。还有一些方法可以使用移动开发工具调试移动Web浏览器。 NodeJS和npm是成熟的项目,是整个JavaScript社区的共享基础架构。
更重要的是,JavaScript作为一种语言已经得到发展。它不再仅仅是我们在1998年所知道的核心语言,也不再是我们在2008年所知道的“The Good Parts”,而是JavaScript的“现代部分”包括几个新的语言特征,名称为“ES6”(ECMAScript v6)或“ES2017”(ECMAScript 2017版)等等。
HTML中的一些概念已经发展,例如HTML5视频和音频元素。随着CSS2和CSS3规范的批准和广泛采用,CSS也在不断发展。JSON几乎完全取代了XML作为交换格式,当然是基于JavaScript的。
V8引擎也获得了大量以性能为导向的开发。它现在是一种JIT编译语言,具有快速启动时间和CPU绑定块的快速近原生性能。现代Web性能技术几乎完全基于快速的JavaScript引擎,并能够编写Web应用程序加载方法的不同元素的脚本。
语言本身已经适应了类似于Python,Ruby,C和Java社区中可能找到的“编译器”和“命令行”工具。代替JavaScript“编译器”,我们有节点,JavaScript单元测试框架,如Mocha / Jest,以及用于语法检查的eslint和babel。
代替“调试器”,我们在我们最喜欢的浏览器中内置了devtools,例如Chrome或Firefox。这包括丰富的调试器,REPL /控制台和可视化检查工具。与节点环境或浏览器进程的脚本化远程连接(通过Puppeteer等新工具)进一步闭环了开发流程。
因此,在2018/2019中使用JavaScript是采用一种已经达到2008年成熟度的系统,您将在Python,Ruby和Java等编程生态系统中看到这种系统。但是,在很多方面,JavaScript已经超越了这些社区。例如,Python 3的参考实现CPython在动态语言方面肯定是快速的,JavaScript的参考实现V8通过JIT和热点优化技术进行优化,这些技术只能在更成熟的编程社区中找到,例如Java(它在Sun时代的应用/高级编译器技术中获得了数百万美元的商业支持。这意味着未经修改的热点JavaScript代码可以由Node运行时和Chrome等浏览器自动优化为本机代码。
虽然Java和C用户可能仍然争论开源项目应该在何处发布他们的版本,但是这个问题在JavaScript社区中得到了解决:它是npm,其操作类似于Python社区中的PyPI和pip。
一些重要的开发人员工具问题最近才解决。 例如,因为现代JavaScript(例如使用ES2017功能编写的代码)需要以旧浏览器为目标,所以需要使用“转换”工具将ES2017代码编译为适合旧版浏览器的ES3或ES5 JavaScript代码。 因为“旧JavaScript”是图灵完整的函数式编程语言,我们知道我们几乎可以将任何新的“语法糖”翻译成旧语言,实际上,新语言特性的设计者正在谨慎地仅引入语法可以安全进行编译。
然而,这意味着要进行JavaScript开发“现代方式”,同时采用其新功能,您只需使用本地转换器工具。 目前社区的标准被称为babel,它很可能在未来很好地保持社区标准。
困扰2008年JavaScript的另一个问题是构建工具和模块化。在2008-2012时代,像make这样的特殊工具被用于将JavaScript模块连接在一起,并且通常使用基于Java的工具(如Google的Closure Compiler或UglifyJS)将JavaScript项目组装到可以包含在页面中的模块中。 2012年,Grunt工具作为JavaScript构建工具发布,在NodeJS上编写,可从命令行运行,并可使用JavaScript“Gruntfile”进行配置。在此期间发布了大量类似于此的构建工具,造成了大量的代码流失和混乱。
值得庆幸的是,今天,像React这样的单页应用程序框架在很大程度上解决了这个问题,其中包括webpack的优势和对npm run-script的依赖。今天,webpack社区已经提出了一种理智的JavaScript模块化方法,它依赖于现代JS对模块的支持,然后主要通过webpack CLI工具提供的开发时工具允许本地开发和生产构建。这可以通过简单的npm run-script命令编写脚本并连接在一起。而且由于webpack本身可以通过npm安装,这使得整个开发堆栈保持自包含的方式与Clojure中的lein或Python中的python / pip不同。
是的,它经历了20年时间,但现在JavaScript已经成为Python后端和CLI工具项目的可行选择。 而且,对于网络前端,它是您唯一的选择。 所以,如果你是一个完全关心代码分发给用户的程序员,那么就该关心JavaScript吧!
有兴趣同学可以关注微信公众号奶爸码农,不定期分享关于投资、理财、IT的信息:
一文道尽JavaScript 20年的发展史的更多相关文章
- 56 道高频 JavaScript 与 ES6+ 的面试题及答案
56 道高频 JavaScript 与 ES6+ 的面试题及答案 :https://segmentfault.com/a/1190000020082089?utm_source=weekly& ...
- JavaScript编写计算器的发展史
JavaScript编写计算器的发展史: 编写一个普通的四则运算: <!DOCTYPE html> <html lang="en"> <head> ...
- HTML文档、javascript脚本的加载与解析
1.onload事件 1.1 onload事件分类 a.文档加载完成事件(包括脚本.图片等资源都加载完),绑定方法:<body onload="doSomething()"& ...
- 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象
JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...
- JS学习之道:javascript keycode大全
keycode 8 = BackSpace BackSpace keycode 9 = Tab Tab keycode 12 = Clear keycode 13 = Enter ...
- javascript 20个正则表达式
正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑.熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升. 正则表达式经常被用于 ...
- 按照vue文档使用JavaScript钩子但是却不能执行动画?
大家刚入VUE肯定是先去阅读文档, 在 进入/离开 & 列表过渡 这一章节有一小节 --------- JavaScript钩子 详情见vue文档: https://cn.vuejs.or ...
- Web 通信技术 ——跨文档信息传输(JavaScript)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.html * 作者:常轩 * 微信公众号:Worldh ...
- VLC的相关文档以及javascript接口
参看下面链接:VLC相关文档
随机推荐
- [leetcode] 263. Ugly Number (easy)
只要存在一种因数分解后,其因子是2,3,5中的一种或多种,就算是ugly数字. 思路: 以2/3/5作为除数除后,最后结果等于1的就是ugly数字 Runtime: 4 ms, faster than ...
- 十九、表添加字段的SQL语句写法
通用式: alter table [表名] add [字段名] 字段属性 default 缺省值 default 是可选参数增加字段: alter table [表名] add 字段名 smallin ...
- php 常用函数总汇
php 使用命令行函数exec($sql,$result,$status); $sql 命令 $result 返回东西 $status成功与否的状态 例如: php使用命令行去执行数据库备份( ...
- js,ts操作dom总结
以上面为例: js获取placeholder节点 : document.getElementsByClassName("newTicket")[0].getAttributeNod ...
- npm常用命令(原创)
1.对于我们下载下来的node包,假设该包存在依赖情况执行: npm install(或者npm i) 下载依赖包: 下载依赖成功过后,文件夹内会产生package-lock.json文件: 2.下载 ...
- HTTP_4_返回结果的HTTP状态码
状态码:返回请求结果. 状态码种类繁多,以下总结常用的状态码: 类别 信息性状态码 1XX 服务器接受请求,继续处理 成功状态码 200 OK 请求处理成功,并返回资源(响应报文中 ...
- HTTP_3_HTTP报文
用户HTTP协议交互的信息被称为HTTP报文 简单的请求报文和响应报文实例 HTTP传输过程中常用设置 提升传输速率 编码压缩传输 (常见压缩格式:gzip compress deflate ) 分块 ...
- handlerMapping的初始化以及查找handler
前提:HttpServletBean初始化了一些servlet配置,接着FrameWorkServlet创建了WebApplicationContext,最后DispatcherServlet初始化一 ...
- 微信小程序onLoad与onShow的区别
现在招聘网站上,会小程序开发都可以找到月薪不错的职位了,可见小程序认可度还是可以的! 小程序声明周期onLoad与onShow的区别? onLoad页面加载时调用,可以获取参数,通过options. ...
- ceph 初始化函数解析
global_pre_init 预初始化函数,解析ceph.conf配置文件, 初始化定义global_context 和 config的全局变量. 全局预初始化函数 CINIT_FLAG_UNPRI ...