TO Rubyist: 此篇属于纯前端的事情,如果不符合你学 Rails 的口味,可以避开哈。
写在前面的话
继上一篇总结之后,觉得必须补充一下 AngularJS 与 Ionic 的技术性话题
于是,昨晚写了这第一篇。
讲述了 AngularJS 与其他对手之间的优与缺。
我有任何理解错误,请指正。
AngularJS 在这两年时光里,可谓是异军突出。我们来看看 Google 搜索指数:
如果你可以顺利翻墙的话,可以看看这个指数链接
现在,可以说,AngularJS 在前端领域,已经占据了主要的地位。
虽然它的诞生,就像 JavaScript 一样带着那样或这样的毛病,但依然大发光彩。
AngularJS 与 JavaScript, 在我看来,都属于 2014 年度最佳框架 (语言).
我们来详细谈谈它的优点与缺点。
有人说,AngularJS 太庞大了,太复杂了,根本就是发展方向错误。实则不然,相反,我的观点是,全栈解决方案远大于简单的方案。
既然我对 Rails 很熟悉,我来举一个 Ruby 界的例子:Rails vs Sinatra. 一个是复杂到 Web 整站解决方案,既包括了后端,还包括了前端,连打包,压缩,布署都帮你做好了。而另一个则是简单到极致,几行代码就可以写一个 Web 服务。然而,Sinatra 永远无法打败 Rails, 只能处于小众圈子。因为只要项目一大,他们就要重新造一遍 Rails 的轮子。
这个时候,大部分人需要的是全栈解决方案,不是小而美的东西。
那么,显而易见,BackboneJS 与 ReactJS 从这个竞争中出局了。
实际上,AngularJS 像 Rails 一样,它内部的轮子是可自由替换的,事实上,全栈的背后也是以简单作为基础的。
EmberJS 是 AngularJS 强有力的对手,有很多支持者,EmberJS 的核心实现也是从 Rails 学到了很多东西。
但为什么大家依然选择了 AngularJS, 我以为真正核心的原因只有一点:一个框架的哲学思想。
貌似有点深奥,实际上很简单:AngularJS 从一诞生,就认定了一件事:在 Web 世界里,声明式语法要远远好于命令式语法。从这一点,就引出了 AngularJS 的主要特性:
而 EmberJS, 一开始就是 Rails 在前端的实现,当然很多概念不适用,并且有些特性又不够,而现在,也是补了许多该有的特性,比如正在开发中的 HTMLBars, View 层无法理解 DOM( HandleBars 只能理解字符串 ) 是一个硬伤,这让 AngularJS 优势太明显了:哲学概念单一,便于理解。而 EmberJS, 更像一个后端的思想的框架,有点水土不服。
或者,应该换个说法:AngularJS 就像官方想做的那样,只是想扩展 HTML 语法,而不得不造了一些概念。而 EmberJS 则是为了实现而实现。如果你深入使用,自会明白我的意思。
AngularJS 真的太容易上手了,当你做过官网上的 Hello World 例子后,你就会惊讶:原来不会 JavaScript 也能写好 Web2.0.
而 Ember 则一开始就教你理解各种概念,controller, action, template, router. 等一等,我们需要一步步向上爬。
随着前端项目的复杂度上升,jQuery 这种命令式语法已经无法管束整个项目的高质量推进。但 AngularJS 也不是银弹。
我们俗话有讲:进入一个世界,往往会放弃另外的世界。这放与 AngularJS 身上非常合适:正是 AngularJS 想把它的哲学思想做到极致,才会带来诸多新的问题:
这几点,相信你只要是 AngularJS 深入使用过都会遇到类似问题。
我们看中它的优点,用它来开发极动感的 AngularJS 前端应用,也须理解并避开它的缺点。
1. 动态作用域
由于 AngularJS 双向绑定的需要,你必须给数据指派一个域 ( scope ), 就像 JavaScript 中的 function, 会将每个不同的域中的数据隔开开来。但不同的是,JavaScript 或 Java 等拥有完整语言特性的语言,它们的 scope 的行为是预定义的,只有有限的几种。而 scope 则不然,你无法真正理解它,就无法理解为什么在 ng-repeat
中修改绑定的值却对应 controller
中的值是无效的一样困惑不解。但是,好的是,当你真正成为程序员时,你就会豁然开朗。
2. 依赖注入问题
这个问题出现的原因也是由于 AngularJS 的哲学导致:依赖概念要够简单。开发者想了一个极取巧的方法:利用参数的名字作为依赖注入的对象。正是因为 JavaScript 的强大多变,他们才能做的到. 然而,新手们总是发现,坑来了:为什么压缩后代码就不能用了?高手们说:我们专门做了个轮子,避免你打包出错。新手们:好牛 X...
3. 双向绑定的性能问题
双向绑定的目的是大大提高我们开发者的效率,却因为当今浏览器引擎的"缺陷"( 无法真正理解事件影响范围 ), 而只能采用最笨拙的思路:
只要有事件触发,就全面执行一次所有的监听 ( watcher ), 如果监听中有新的值出现,则再次执行所有的监听,进行重新计算,反复最多 10 次。
这里就不解释原理了。简而易见,这里可能有性能问题。
但经过测试,只要绑定对象不超过 2000 次,则每一次 loop 都不会超出 50 ms. 这个时间差对我们人眼是无感知的。
但我认为,比起这一点潜在的性能问题 ( 而且是可以轻松调优的,chrome 下有很好用的插件 ), 我们还是值得去学习应用 AngularJS 的。
4. directives 不必要的复杂度
这个问题是唯一一个从设计上欠考虑的模块了。directives 是一个好东西,你可以用它来封装各种 HTML 操作,然后把它们做成组件。这个特性太酷了。
本来,一鼓做气,就可以把 ReactJS 比下去,可是,由于设计缺失。我们只能得到一个半成品:
AngularJS 依然拥有不可比拟的优势,占据前端开发框架之首也是理所当然。但 AngularJS 第一代框架确实不够大气,第二代框架又太超前,我们也不得不像使用 JavaScript 那样"坑"的语言那样来使用 AngularJS 了。因为,我们确实找不到更满意的取代品了。
更为可喜的是,AngularJS 的测试框架设计的极为出色,这也让它能够不断快速迭代,也让我们写的应用更为健壮。
这也是我选择一个框架的原因之一。
ps: 我是技术达人李亚飞 (微信公众号), 也欢迎关注我的博客:http://yafeilee.me