资讯专栏INFORMATION COLUMN

[译]JSX:硬币的另一面

mudiyouyou / 2044人阅读

摘要:它不过是硬币的另一面。因此,既然我们能够接受与通过这种方式混合在一块儿,那么是时候让介入并向我们展示硬币的另一面了第三阶段的并不是一个激进的改变,是因为我们这个行业从一开始就注定和应该是在一起的。

React框架刚刚发布的时候,JSX颠覆了很多人的想法。习惯了HTML标签与JavaScript代码分离的前端工程师们,看到JSX大概都会不禁吐槽:“这些奇怪的标签出现在JavaScript里是要干啥?!”我们一向贯彻的关注点分离原则呢?Facebook的工程师难道一点都不了解这些社区中已经默认的规范?

像很多人一样,我一开始对JSX这种语法是持怀疑态度的。甚至当我爱上JSX后,每次我向别的开发者推荐这种语法,我都会觉得我是在向别人展示我丑陋的孩子。

从一开始的怀疑到爱上JSX,我渐渐意识到JSX其实并没有那么激进。它不过是硬币的另一面。JSX其实是前端开发中自然进化的一个过渡。为什么这么说呢,我们有必要回顾一下前端这几年的发展历程了。

第一阶段:非侵入式JavaScript(Unobtrusive JavaScript)

还记得那个jQuery盛行的时代么?非侵入式的JavaScript被各种提倡。我们的HTML是纯HTML,我们的JavaScript是纯JavaScript。我们开发时是严格贯彻所谓的关注点分离的。

我们像下面这样写HTML:

Click to hide me

而我们的JavaScript会这样写:

$(".hide").click(function() { 
    $(this).hide(); 
})

按照之前的理解,这样做是真的做到了关注点分离对吧?然而我觉得并不是这样。

这样写看起来像是一个好主意。我们的HTML是绝对纯净的,完全不参合任何逻辑代码。但是我们会慢慢发现一个问题:我怎么知道哪行JavaScript代码在控制我的HTML呢?答案是:除非我阅读了整个JavaScript文件,我才能明白,哪段JavaScript代码在控制哪段HTML。(译者注:这样的情况很常见,尤其是在大型项目中,我们有无数的还有可能重复的DOM节点,HTML和JavaScript文件不在一起,要修改起来简直太复杂了)。在这种模式中,你不能仅仅简单的修改一个标签而不去检查对应的JavaScript代码以确保你的修改没有破换选择器执行。你看,这里实际上并没有实现关注点分离,我们还是要不断的关注HTML和JavaScript之间的联系。我们做到的仅仅是把JS和HTML分离到了两个不同的文件中。在本质上这两种技术是密不可分的,他们必须保持步调一致,否则就会导致我们的应用崩溃。

直接分割HTML和JS导致我们的应用更加难以维护和调试。每次你想修改一个标签,总是会担心破坏一个jQuery选择器。如果我们对关注点的分离不那么严格,也许可以减轻一些痛苦。于是,我们迎来了第二阶段...

第二阶段:双向绑定(Two-way Binding)

在Knockout和Angular中出现的双向绑定,让所有前端开发者眼前一亮。许多开发者开始抛弃之前信奉的关注点分离,并全力拥抱这种在HTML标签中声明式绑定的力量。当数据发生改变,UI也自动发生变动。当UI发生变动,数据也随之变动。如此清晰,如此简单。(译者注:我认为这是另一种意义上的关注点分离,我们不再需要关注HTML与JavaScript之间的联系,我们需要做的就是维护好数据。)

这些框架的实现的确大不相同,但他们都在试图做相同的事情。试想使用这几个流行框架实现迭代数组这个例子:

//Angular
//Ember {{#each user in users}} //Knockout data-bind=”foreach: users”

但是这里出现了一些有意思的事情————很少有人意识到一个非常显著的问题:我们实际上在把JavaScript放到HTML中。这并不是我们所理解的那种关注点分离。我们可以发现这些框架都在处理同一件事:通过为HTML添加额外的特殊标记使其更强大。这些标记可以被解析为JavaScript。因此,既然我们能够接受JavaScript与HTML通过这种方式混合在一块儿,那么是时候让React介入并向我们展示硬币的另一面了...

第三阶段:JSX

React的JSX并不是一个激进的改变,是因为我们这个行业从一开始就注定HTML和JavaScript应该是在一起的。

只有当你体验过React和JSX之后,才能体会到这样做有多少好处。React的JSX完全优于所有的“第二阶段”风格的框架的原因有以下几点:

编译时错误(Compile-time Errors)

当你的HTML中出现输入错误时,你很难知道自己是哪里写错了。在很多情况下这是一种无声的运行时错误。比如,如果你在写Angular应用时输入n-repeat而不是ng-repeat,什么都不会发生。当你在写Knockout应用时把data-bind写成data-bnd,也同样什么都不会发生。在出现这些错误时,你的应用会悄无声息的运行时失败。这太令人沮丧了。

相比之下,当你在JSX中发生类似的输入错误时,它是不会被编译的。忘记闭合

  • 标签了?难道你不想在你输入错误的HTML时得到丰富的反馈么?

    ReactifyError: /components/header.js: Parse Error: Line 23: Expected corresponding JSX closing tag for li while parsing file: /components/header.js

    有了JSX,这样丰富的错误反馈终于成为现实!靠这一点JSX绝对完胜。如此快速而又丰富的反馈极大的提高了生产效率。正如我在我的Clean Code课程中讨论的那样————良好的工程解决方案遵循速错原则。(译者注:原文是:well- engineered solutions fail fast,关于fail fast可以查看http://geeklu.com/2010/07/fai... 进行了解)

    充分利用JavaScript(Leverage the Full Power of JavaScript)

    使用JavaScript编写你的标记,意味着这些标记可以借助JavaScript的全部能力,而不是像Angular或者Knockout这种以HTML为中心的框架只能提供有限的特殊标记。(译者注:我认为这里作者的表述并不准确,Angular也同样可以自由扩展HTML,只不过没有React那么灵巧方便)。

    Client-side frameworks shouldn’t require you to learn a proprietary syntax for declaring loops and conditionals.
    客户端框架不应当要求使用者学习特殊的语法来声明循环或者条件语句。

    React减少了使用者学习另一种特殊的声明循环和基本条件语句的成本。你可以看看第二阶段中提到的几个框架,他们实现双向绑定的方式都是依靠一些属于他们自己的特殊语法。相反,JSX看上去和HTML几乎一样,像循环和条件语句,完全依赖原生的JavaScript。与众多的JavaScript框架相比,不需要去学习类似于数据绑定等特殊语法,这一点又让React和JSX脱颖而出。

    并且,由于你将这些标记与相关联的JavaScript数据写在一个文件中,当你引用函数时,许多IDE能够提供一些智能提示。想想当你使用那些以HTML为中心的框架时,调用一个function却总是输入错误时的苦恼吧!

    Final Thoughts

    JSX并不一个疯狂的主意,它就是一段很正常的程序,因此不要再反感它了。

    JSX isn’t revolutionary. It’s evolutionary.

    JSX不是革命,它只是进化发展的结果。

    像很多进化、演变一样,它给我们带来的是一种改善。

    原文链接:https://medium.com/@housecor/...

  • 文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/81658.html

    相关文章

    • [] 逐渐去掌握 React(作为一名 Angular 开发者)

      摘要:你是一个对感兴趣的开发者吗不用担心,这真的不会让你成为一个背叛者或其他什么,真的。事实上,这个想法并不是或独创的它只是一种很棒的软件开发实践方式。把代码分离到不同的文件里并不会自动导致关注点分离。 原文链接 : Getting to Grips with React (as an Angular developer)原文作者 : DAVE CEDDIA译者 : 李林璞(web前端领域)...

      channg 评论0 收藏0
    • [] W3C vs. WhatWG HTML5 标准 - 差异记录

      摘要:问题在于标准是同一硬币的一面。然后,又改名为现存标准来指定它将不断发展和不再支持使用版本号引用。作为这一步的结果,该组织正在积极开发的标准被称为新版本。所以,删除版本号使其具有连续性听起来是比较合理地。特别地,标准去掉了和事件。 原文地址:http://developer.telerik.com/featured/w3c-vs-whatwg-html5-specs-difference...

      ShevaKuilin 评论0 收藏0
    • []基于 React Router 4 的可复用 Layout 组件

      摘要:通过向组件提供属性,我们可以控制属性的渲染。在这种情况下,我们将其包含在包含页眉和页脚的中,但这可能只是把其他组件做了简单的分组。仅此而已短小精悍。的新版本专注于使用组件模型,而这些组件可以非常简单的组合在一起。 本文翻译自:Reusing layouts in React Router v4 在 React Router V4 应用中,希望在每个路由上呈现一些默认的组件,比如页眉和页...

      用户83 评论0 收藏0
    • 理解CKB的Cell模型

      摘要:交易依然表示状态的变化迁移。这样一个模型的特点是状态是第一性的所有者是状态的属性,每一份状态只有一个所有者状态不断的被销毁和创建。值得指出的是,的编程模型之所以强大,更多是因为它有状态,而不是因为它的有限图灵完备。 在设计 CKB 的时候,我们想要解决三个方面的问题: 状态爆炸引起的公地悲剧及去中心化的丧失;计算和验证耦合在了一起使得无论是计算还是验证都失去了灵活性,难以扩展;交易与价...

      henry14 评论0 收藏0
    • 对比特币的继承与创新!深入理解公链 CKB 的 Cell 模型

      摘要:为了理解底层公链的模型,我们前置了几篇概念性文章,讲述了我们应该以状态为中心设计区块链系统的,以及这么做带来的好处。交易依然表示状态的变化迁移。 为了理解底层公链 CKB 的 Cell 模型,我们前置了几篇概念性文章,讲述了我们应该以状态为中心设计区块链系统的,以及这么做带来的好处。并且在上一篇文章中,详细分析了比特币 UTXO 模型和以太坊的 Account 模型,以及进行了对比分析...

      ruicbAndroid 评论0 收藏0

    发表评论

    0条评论

    mudiyouyou

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <