精华

  [原创译文] 2016年学习Javascript是一种什么样的体验?

Author Avatar calidion 发表于 • 2016年10月21日 06:18 • 共 • 747 • 次浏览

原文地址:

https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f#.wz2znxn1u

下面的内容是被Circle CI的文章《这是未来》所激发的。你可以在这里找到这篇文章: https://circleci.com/blog/its-the-future/ 这篇文章只是表达一种观点,就象任何javascript框架一样,不要对它太较真。希望在我写这篇文章的时候没有新的框架被创建出来。

“你好啊,我刚接手这个新的Web项目。但是最近几年我基本没有写过多少Web代码,我听说现在情况已经发生了很大的变化了。你是这里最了解前沿技术的Web开发者,没错吧?”

嗯。差不多吧。准确的说法是前端工程师。在2016年从事Web开发,玩可视化,音乐播放器以及用无人机打足球之类的人。我刚从JsConf和ReactConf回来,所以我知道最新的创建Web App的技术。

“酷!我现在需要创建一个显示用户最新活动的单面,需要从REST端获得数据然后将数据显然有筛选能力的表格上,并随服务器的变化更新。我在想我可不可以使用jQuery去获取并显示数据?”

我晕。现在谁还用jQuery。你应该学习React了,都2016了。

”哦。这样。React是什么呢?“

Facebook的一些工程师搞得超酷的库,它可以允许你很方便的处理view的改动,给你的应用带来实际的性能提升和控制能力。

“不错。我可以使用React显示服务器数据吗?”

是的。不过你要先将React和React DOM当作库添加到你的页面里。

“哦,怎么是两个库?”

一个是实际的库,另一个是用于操作DOM的库,有了它你才可以使用JSX描述。

“JSX?什么是JSX?”

JSX只是一个Javascript语法扩展,它看上去有点象是XML。它有点类似于描述DOM的另一种方式,可以看作是更好的HTML。

“那HTML有什么问题吗?”

现在都2016年了,没有人直接使用HTML写代码的啊。

“好吧。那就是说,如果我添加了这两库就可以使用React了?”

不完全是。你需要添加一下Babel,然后就应该就没有问题了。

“是另一种库?Babel是什么?“

Babel是一个转换器,可以允许你使用任何版本的Javascript转化到特定的Javascript版本上去。你不是必须包含Babel,但是如果不是这样的话,你可能只能使用ES5了。并且如果从实际出发,考虑到已经是2016年了,你最好使用ES2016+进行编码,大牛们都这样使用。

ES5?ES2016+?有点晕!什么是ES5和ES2016+?

ES5表示ECMAScript 5。这是拥有最大用户的版本,大部的浏览器都已经实现它了。

”ECMAScript?“

是的。它是一种脚本标准,它在1995发布,在1999年开始成为Javascript的基础。之前Javascript叫Livescript并且只能在网景(Netscape)的Navigator上运行。刚开始时,这玩意是非常混乱的,不过,现在已经非常清楚。并且我们已经差不多有7个版本的实现。

“7个版本的实现。那么,ES5和ES2016+也是?”

它们分别是第5与第7版本。

“ 跟第六版没有一毛钱关系?”

你是说ES6?其实每个版本是一个前一个版本的超集,所以如果你使用ES2016+的话,你能使用之前版本的所有属性。

“好的。那为什么要使用ES2016+而不是ES6呢?”

你当然可以使用ES6。但是如果你想使用async和await这些很帅的特性的话,你还是得使用ES2016+。否则你可能会掉到ES6的generator的坑里去。它是使用coroutine来阻塞异步调用来实现更好的流程控制的。

“你刚才在讲毛线,这些名字把我搞晕了。我其实只需要加载一些服务器数据而已,我之前是从CDN上加载jQuery然后通过AJAX调用获取数据的,为什么我不能那样弄呢?”

都2016年了,哥们。谁还用jQuery啊,它会导致代码一坨一坨的。这个大家都有知道。

“好吧。那就是说我要加载3个库,然后获取数据并显示在HTML表格上。”

不是的,你包含这三个库,然后通过模块管理器将他们合并成一个文件。“

”什么是模块管理器?“

这个定义跟环境有点相关,但是在Web领域,我们通常是指任何支持AMD或者CommonJS模块的管理器。

”好..吧!AMD和CommonJS是什么玩意?”

两种规范。它们用来描述多个Javascript库、类如何交互的。包括如何输出(export)参数以及如何引入(require)库。然后你就可以编写多个Javascript文件,并定义它们的AMD或者CommonJS API,然后你再通过类似于Browserify的东西打包它们。

“OK,貌似可以理解…不过Browserify又是什么鬼?”

它是一个允许你打包CommonJS描述的依赖文件的工具。从而让代码可以在浏览器上运行。因为很多人通过npm注册表发布依赖。

“npm注册表?“

它是一个很大的公共库,很多牛人将代码与相关的依赖做成模块放在那里。

“就象是CDN?“

不是。它更象是中心化的数据库,任何人可以发布并且下载。所以你一般在本地开发并且在必要的时候发布到CDN上。

“哦,象Bower!“

是的。不过现在已经是2016年了,没有人使用Bower了。

”哦,这样…所以我需要从npm下载这些库?“

是的。举个栗子,如果你想使用React,你下载React模块,然后import到你的代码里。当然你可以对几乎所有的流行库这样做。

“哦,那象Angular也可以吧!“

Angular太2015了。不过也算是的。Angular也会这样,包括VueJS或者RXJS以及其它很酷的2016年的库。需要介绍这些库吗?

”我们还是继续聊React吧。我已经学了太多东西了。所以,如果我需要使用React,我需要从npm获取,然后使用Browserify这样的东西?“

是的。

”看起来有点复杂过头了,还要获取所有的依赖,然后把他们合并起来。“

是的。所以你需要一个任务管理器,象Grunt/Gulp/Broccoli,来自动运行Browserify. 差点忘了,也可以使用Mimosa。

”Grunt? Gulp? Broccoli? Mimosa?我们这是在讨论啥?“

任务管理器。不过他们已经不是最酷的技术了。我们在2015年使用他们,然后我们也用过Makefile,不过现在我们全部使用Webpack了。

”Makefiles?我想它主要是用在C/C++项目里的。“

是的。不过很显然,在Web领域,我们喜欢让事情先变的复杂起来,然后再回到基础。差不多每年都会这样做,你只要再等等,一到两年内在web上就可以使用汇编了。

”无语。Webpack又TMD的是什么东东?“

它是另一个用于浏览器端的模块管理器同时又有点任务运行器的功能。有点象是一个更好的Browserify。

”哦。好吧。为什么更好?“

怎么说呢,可能也不一定更好。它可能只是在你的依赖如何组织上更加有自己的看法。Webpack允许你使用不同的模块管理器,不只CommonJS的,也可以支持原生的ES6模块。

”你妹,我已经完全被CommonJS/ES6这些事情搞晕了。“

基本所有人都会跟你一样一开始蒙圈。不过有了SystemJS,你就可以不用管这些了。

”我艹。又来新的JS名词了。好吧。那SystemJS又是什么?“

跟Browserify和Webpack 1.x差不多,SystemJS是一个动态模块加载器可以允许你将多个模块在多个文件中串联起来而不用将他们合并到一个文件。

”等下,我想我们想要的是将我们的库放到一个文件然后加载进来!“

是的。不过因为HTTP/2就要来了,多次HTTP请求实际上会更好。

”纳尼!所以我们不能只添加三个库的原始文件到React?“

也不是。我的意思是。我们可以将他们作为外部脚本从CDN添加,但是我们还是需要添加Babel的。

”晕死。这种方式不好?“

是的。这样你需要包含所有的babel-core代码,这样对于生产环境来说是没有效率的。在生产环境,你要执行一系列的前置任务才能让你的项目准备好。会让简单的事情变的很复杂。你需要压缩assets,并uglify它们,插入不同目录的css,区分不同的脚本,还有…

”打住,打住!如果不直接从CDN引入库,那应该怎么做?“

我会使用Webpack+SystemJS+Babel组合从Typescript进行转化。

”Typescript?我们难道不是在讨论Javascript编码!”

Typescript其实也是JavaScript,准确的说是一个超集,更确定的说是一个基于ES6的超集。还记得吗,第6版我们刚才有提到?

"ES2016+不是已经是一个ES6的超集了吗?为什么我们还需要这个叫Typescript的东西?"

哦。因为它允许你象一个强类型语言一样使用Javascript,从而减少运行时错误了。现在已经是2016年了,你应该在你的Javascript代码里添加一些类型了。

“就是Typescript是做类型检测的?”

还有Flow。虽然它只检测类型,而Typescript是一个Javascript的超集,但是Typescript还需要编译。

“又来个Flow?“

一个静态类型检测器,Facebook那帮家伙弄的。他们用OCaml写的,函数式编程确实很牛逼的。

”OCaml? 函数式编程?“

这些都是那些大牛们用的技术,哥们。2016年了,你知道还有函数式编程?高阶函数?柯里化(Currying),纯函数(Pure functions)?

”都没听过!“

也没什么。不过,你知道函数式编辑比OOP要好并且那是我们要在2016年使用的即可。

“等下,我在大学里学的是OOP啊。我觉得它挺好啊?”

是的。跟Java被Oracle收购前一样的好。我的意思是过去OOP是挺好的,并且它现在也是有用的。但是现在所有人都意识到修改状态是很蛋疼的事情。所以大家都迁到不变对象(immutable objects)与函数式编程上来了。Haskell那帮人已经使用它们很多年了-最好不要让我扯到使用Elm的那帮人-不过很幸运的是在Web开发领域我们已经有了Ramda这样的库,从而可以让我们使用纯javascript来进行函数式编程。

“尼玛又为这了个给我掉书袋子?Ramda又是什么鬼?”

没有哦。Ramda。象Lambda。你知道,他是David Chambers的库。

“David是谁?”

David Chambers, 一个大牛。 喜欢玩策略游戏。一个Ramda的贡献者。如果你想认真的学习函数式编程,你还需要了解一下Erik Meijer.

“Erik Meijer是?“

也是函数式编程的大牛。他有很多演讲将敏捷抨击的一无是处。对了,你还需要了解一下这些人: Tj, Jash Kenas, Sindre Sorhus, Paul Irish, Addy Osmani

“好了。我想你还是先打住。这些都很好。不过我想所有那些东西都太复杂也没有必要,对于只要获取数据并显然的情况来说。我肯定我不需要知道这些人或者学习所有这些东西,而仅仅为了创建一个具有动态数据的表格。我们还是回到React上来。告诉我如何使用React从服务器获取数据?”

这么说吧,你实际上并能通过React获取数据,你通过React显示数据。

“哦。玩我呢!那你用什么获取数据?“

你应该使用Fetch来fetch(获取)服务器数据。

”EXO me?用Fetch来fetch数据?名字什么鬼?“

嗯嗯,其实并没有问题?Fetch是指完成XMLHttpRequest请求服务器的原生实现的对象名。

“哦,那就是AJAX?”

AJAX是指只使用XMLHttpRequest。Fetch允许你做基于许诺器(Promise)的AJAX,然后调用resovle,从而避免回调地狱(Callback Hell)了。

”回调地狱(Callback Hell)?“

是的。 每次向服务器发起异步请求,你都需要等待它的响应。这时需要你添加一个函数到另一个函数。这种情况被称为来自地狱的回调金字塔。

”哦。好的。然后许诺器(Promise)解决了这个问题?“

差不多。通过许诺器(Promise)来管理你的回调函数,你可以编写更加容易理解的代码,模拟并测试它们。甚至同时请求并等待他们全部加载完毕。

”那些Fetch都能完成?“

是的。除非你使用全功能(原文全绿:表示通过所有特性)的浏览器,否则你需要添加一个Fetch的补丁(polyfill)或者使用Request,Bluebird,Axios什么的。

”我究竟需要知道多少库,还有多少这样的库?“

对于Javascript来说。差不多有上千个这样的库做同的事情。我们知道有很多库,并且有些是最好的。我们的库非常庞大,并且有时我们会包括Guy Fieri的照片之类的。

”Guy Fieri?我们还是别扯这些了。说说Bluebird, Request, Axios这些库是干什么的吧。“

它们是返回许诺器(Promise)的XMLHttpRequest库

”jQuery还没有开始返回许诺器吗?“

在2016年里我们不再使用“J“这个词了。只使用Fetch和补丁如果不在浏览器的话,或者使用Bluebird, Request和Axios。然后在一个async函数里控制许诺器(Promise)使用await,直到执行结束,这样你就会有一个良好的控制流程。

”好象是第三次提到await了,不过我还是没什么概念。”

await允许你阻塞一个异步请求,允许你在数据请求完成后有更好的控制,以及整体上提升代码的可读性。它用起来很爽,你只需要确保你添加了stage-3的前置条件或者使用syntax-async-functions和transform-async-to-generator插件就可以了。

”疯掉。”

这还不算太疯。真正疯狂的是你需要编译Typescript代码后然后再通过Babel转换后才能使用await.

“什么?Typescript上没有包含?”

下个版本会包含,但是对于1.7版本来说,他只针对ES6。所以如果你想在浏览器使用await,首先你需要先编译成ES6,然后通过Babel转换成ES5.

“无语!“

其实也容易。所有代码使用Typescript写。所有模块使用到Fetch的编译成ES6。将他们基于stage-3放在Babel上转换,并使用SystemJS加载。如果你没有Fetch,打个补丁,或者使用Bluebird, Request或者Axios中一个。对所有的许诺器使用await。

”感觉我们对于容易的理解不太一样啊!这样我就可以得到数据,然后使用React显然数据了吗?“

那你的应用会处理各种状态变化吗?

”哦。我想应该不用。我只需要显示数据即可。“

哦,感谢老天。否则我还得向你解释Flux了以及Flummox, Alt, Fluxible这些实现。虽然老实说你应该使用Redux。

“我想还是快速的过掉这些名字。我再说一下,我只需要显示下数据。“

哦。如果你只是要显示数据,你其实都没有必要使用React。你可能只需要一个模板引擎即可。

”你TMD在逗我?@#$%**&!!!你觉得这样很好玩?你就这样对你的小伙伴?“

我只是告诉你,那些是你可以使用的。

”停。就先这样!“

我想说其实是,即便只是使用模板引擎,我也会使用Typescript + SystemJS + Babel的组合。如果我是你的话。

”我只需要显示数据到一个页面上,不是去打怪升级造城堡。告诉我用那个模板引擎,我去拿过来用就行了。“

有很多模板引擎,不知道你熟悉那个?

“嗯? 我记不得名字了,很久以前貌似用过。

jTemplates? jQote? PURE?

“不对,对不上号。还有其它的?“

ransparency? JSRender? MarkupJS? KnockoutJS? 这个有双向绑定的能力

”还有吗?“

PlatesJS? jQuery-tmpl? Handlebars?不少人还在用。

“貌似有点意思。还有没有跟最后一个比较象的?”

Mustache, underscore?我想即使lodash现在可能都有模板功能了,不过这几个是2014年的。

“不对,我那个似乎要新一点。”

Jade? DustJS?

“不是“

Nunjucks? ECT?

“不是。”

没错,应该没有人喜欢Coffeescript的语法了。JADE?

“不是。你已经说过JADE了”

我的意思是Pug。其实也是JADE。我的意思是JADE现在叫Pug.

“晕,不是。想不起来了。你用那个?“

我可能会使用ES6的原生字符引擎。

”我猜这个需要ES6的支持?“

是的

”然后根据我使用的浏览器还要使用Babel?“

没错。

“然后如果我不想加载整个核心库,我需要从npm里将它当成是一个模块加载进来?”

是的。

“然后要使用到Browserify或者Webpack或者相近的SystemJS?”

是的。

“然后,除非使用Webpack,最好还要有一个任务运行器”

是的。

“但是,由于我要使用函数式编程,以及类型语言,我首先要将Typescript预编译或者添加这种流程上的事情”

是的。

“然后将生成的内容发送给Babel,如果我想使用await的话”

是的。

"这样我就可以使用Fetch, 许诺器(Promise)和流程控制这些魔性的玩意了。"

别忘记了给Fetch添加补丁,有些还没有支持它,比如Safari。

"完完!就聊到这里。我放弃!不想弄Web了,也不想弄Javascript了!"

没问题。不过几年后,我们可能能使用Elm或者WebAssembly写代码了。

"我还是回到后端吧。我感觉无法处理这么多变化,版本号,改动,编译器,转换器。Javascript社区已经疯掉,这节奏鬼才能跟得上。"

可以理解。不过建议你去了解下Python社区。

“纳尼?”

听过Python 3吗?

“…“

最后编辑于 • 2016年10月21日 06:18 •  

你尚未登录,无法进行回复。