AngularJS AngularJS 为什么成功了?

lyfi2003 · 2015年01月13日 · 最后由 nightire 回复于 2015年01月13日 · 19685 次阅读

TO Rubyist: 此篇属于纯前端的事情,如果不符合你学 Rails 的口味,可以避开哈。

写在前面的话

继上一篇总结之后,觉得必须补充一下 AngularJS 与 Ionic 的技术性话题

于是,昨晚写了这第一篇。

讲述了 AngularJS 与其他对手之间的优与缺。

我有任何理解错误,请指正。

AngularJS 的成败

AngularJS 在这两年时光里,可谓是异军突出。我们来看看 Google 搜索指数:

如果你可以顺利翻墙的话,可以看看这个指数链接

现在,可以说,AngularJS 在前端领域,已经占据了主要的地位。

虽然它的诞生,就像 JavaScript 一样带着那样或这样的毛病,但依然大发光彩。

AngularJS 与 JavaScript, 在我看来,都属于 2014 年度最佳框架 (语言).

我们来详细谈谈它的优点与缺点。

全栈 VS 简单

有人说,AngularJS 太庞大了,太复杂了,根本就是发展方向错误。实则不然,相反,我的观点是,全栈解决方案远大于简单的方案。

既然我对 Rails 很熟悉,我来举一个 Ruby 界的例子:Rails vs Sinatra. 一个是复杂到 Web 整站解决方案,既包括了后端,还包括了前端,连打包,压缩,布署都帮你做好了。而另一个则是简单到极致,几行代码就可以写一个 Web 服务。然而,Sinatra 永远无法打败 Rails, 只能处于小众圈子。因为只要项目一大,他们就要重新造一遍 Rails 的轮子。

这个时候,大部分人需要的是全栈解决方案,不是小而美的东西。

那么,显而易见,BackboneJS 与 ReactJS 从这个竞争中出局了。

实际上,AngularJS 像 Rails 一样,它内部的轮子是可自由替换的,事实上,全栈的背后也是以简单作为基础的。

思想的背后

EmberJS 是 AngularJS 强有力的对手,有很多支持者,EmberJS 的核心实现也是从 Rails 学到了很多东西。

但为什么大家依然选择了 AngularJS, 我以为真正核心的原因只有一点:一个框架的哲学思想。

貌似有点深奥,实际上很简单:AngularJS 从一诞生,就认定了一件事:在 Web 世界里,声明式语法要远远好于命令式语法。从这一点,就引出了 AngularJS 的主要特性:

  1. 双向数据绑定
  2. 永不操作 DOM

而 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 想把它的哲学思想做到极致,才会带来诸多新的问题:

  1. 动态作用域问题
  2. 依赖注入问题
  3. digest loop 双向绑定性能问题
  4. directives 不必要的复杂度

这几点,相信你只要是 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 比下去,可是,由于设计缺失。我们只能得到一个半成品:

  1. 语法定义非常蛋疼
  2. scope 在其中非常绕,难于理解
  3. parser, link 等对于普通开发人员暴露的东西太多,而难于理解。而问题是,对于我们普通开发者而言,这个 directives 特性是我们必修的。

总结

AngularJS 依然拥有不可比拟的优势,占据前端开发框架之首也是理所当然。但 AngularJS 第一代框架确实不够大气,第二代框架又太超前,我们也不得不像使用 JavaScript 那样"坑"的语言那样来使用 AngularJS 了。因为,我们确实找不到更满意的取代品了。

更为可喜的是,AngularJS 的测试框架设计的极为出色,这也让它能够不断快速迭代,也让我们写的应用更为健壮。

这也是我选择一个框架的原因之一。

ps: 我是技术达人李亚飞 (微信公众号), 也欢迎关注我的博客:http://yafeilee.me

用 Angular,你就是 Angular 开发者。用别的,你是 Javascript 开发者。

隔壁 v2ex 也是你发的吧

用 Rails,你就是 Rails 开发者。用别的,你是 Ruby 开发者^_^

@hooopo 你是码农!

我现在是个准 emberjs 开发者,我的博客 http://blog.yunnuy.com/ 有几篇关于 ember 的文章,
自己还打算维护一个使用 emberjs 的纯 js 的 web 开发框架 meen.

参照楼主的 1, 2, 3, 4, 聊一聊:

  1. 动态作用域。貌似没这个问题,MVC 分层妥妥的。
  2. 依赖注入。对象可以手动生成否则 ember 会自动生成,可以利用容器获得生成的对象。
  3. 双象绑定性能问题。在 ie8 下面碰到性能问题,最简单的渲染,输出 130 个元素的数组,就出现 "long running script" 警告。仅 ie8 和以下。
  4. 这个是声明式组件嘛?就对应 ember 中的 组件吧。这个和 view 是一样一样的,只是默认没给它上下文。所以没有额外的复杂度。

另 ember-data 很强大,坑也不少..

#6 楼 @feitian124 已订阅 #5 楼 @nightire 我觉得 看起来 AngularJS 成功 的另一原因是,国内已有翻译完成的关于 AngularJS 书。而关于 Ember 的书一本都没有。这样国内开发者,在选择学习上,必然倾向于 AngularJS 吧。

觉得 angular 和 ember 不分上下。

#2 楼 @est 嗯,是的:) 我本想以为咱们 Rails 社区不喜欢聊前端,所以没有第一时间发这里。

#5 楼 @nightire 我觉得凡事就是多探讨才有提高,所以发出文章来看看大家的理解。

#6 楼 @feitian124 发现已经前不久就关注了:) 我并没有厚此薄彼,会继续关注这个领域的发展。

使用 AngularJS 的感受:

  1. 容易上手,但仅仅是上手,上手后有着漫长的学习路线
  2. 如果要深入学习的话,对原生 JS 的功力要求较高
  3. 需要很好的理解不同组件的职责
  4. 有时间的话建议阅读部分源码,很有收获

你也太 Niu 了!

我现在倒更看好 emberjs(虽然我一年半前看好 angularjs),Emberjs 强调的 routing 概念对现实的 SPA 程序太重要了,HTMLbar 现在已经可以理解 HTML 了,另外作者正在做 fastboot,优化首页性能,还有就是配合 Ember-data 基本就是 rails 的完全版,还有就是升级策略比 angularjs 好太多太多,Angularjs 2.0 很可能变成第二个 python 3000

#10 楼 @lyfi2003 是啊,凡事多探讨才有提高,这是没错的。不过我说说你这篇文章的问题也请不要介意。

你做的很多对比,特别是特性方面的对比,第一是很含糊,往往一句话带过,并没有把 pros & cons 说清楚;第二则是对于做对比的对象,比如 Ember 和 React 等,理解都不到位,甚至有明显的错谬之处。感觉上已经不是要探讨,而是在输出价值观了——当然你可以说我小题大做了,我并不想挑起事端,只是作为“过来人”说一下阅读之后的感觉。

就我个人来说我是很不喜欢对比文的,原因就是我前面回复的最后一段。当然我也不是说对比文就没有价值,只是但凡拿一个东西和另外的东西对比就得小心小心再小心,因为对它们都不太熟悉的人来说,这些对比所反射出的“事实”会真切的影响到读者的感官。

无论是 Angular 还是 Ember 还是其他,我在初学的时候也经常找一些对比的文章看,可后来长期的实践让我明白我受这些对比文的“坑害”远比得到的益处要大。

如果是要探讨,我觉得就不要摆出结论,比如谁谁谁是胜利者,谁谁谁是第一,结论都摆出来了还探讨啥啊。不妨拿出一个或几个特性点,把自己喝竞争对手的 pros & cons 一五一十摆出来,再加上代码演示那最好,这样才有探讨的价值。否则就容易变成我说的那种“槽点太多,不知从何吐起”了。

#7 楼 @Victor 对,你说的这个因素很客观。

补充一点,我眼中的“成功”可能和大家说的“成功”有些区别,我看多数人定义 Angular 的成功都是基于使用者人数,换句话说就是谁的小弟多谁就成功。我不觉得这不对,只是我对“成功”的定义更苛刻一些吧,我认为只有在懂行的人眼中能真正分出个高下来那才是“成功”,而不是看谁的呼声更高。

如果那用户基数等指标来比,Angular 说它胜出我绝无意见,但这篇文章说胜出却不是这一点,而是用很多特性对比来作证 Angular 的“成功”,若是这些对比有理有据令人信服也就罢了,可惜并非如此。

个人认为,转了一大圈,说到底还是要解决实际问题呀,不能忘记这个初衷 #14 楼 @nightire 赞同你的看法,另外,其实我觉得前端变化的速度也真的是太快了,还是要慢慢回到语言本身,才是根本,才是以不变应万变之法

在 HackerNews 上刚好也看到楼上 Rei 贴的文章链接。刚好最近也学了一段时间的 Angular,说下我作为初学者的感受吧:

  1. Angular 仅仅是容易上手,入门 demo 效果出的很快,但我在做完 demo 之后其实感觉还是很混沌,因为它提出的概念实在太多了,这个问题直到我去爬完了官方指南之后才能基本解决。此外,对于一个理解了 Rails 的 MVC 运作机制的初学者来说,Angular 的 model, view 一开始让我有点困惑,直到要去了解了 scope 在其中扮演的核心作用之后才能把整个工作机制理清楚。

  2. Angular 的内部设计不可谓不复杂,但几乎是在现有 js 开发的概念上重建了一套自己的概念,给我的使用感觉是用 Angular 写 app 和用别的 任何 js 框架/库 写 app 是完全不同的两个思路,也就是说我很可能要冒着紧抱 Google 大腿的风险,然后我发现了他们在准备 2.0 了,还不向后兼容。

  3. 如果只是用关注度来说,无疑它是“成功的”。但越大的项目就越难维护,如果前端工作只用一个大而全的框架做,会不会也掉到这个问题里呢?反而如果是前端的工作可以分开成各个功能性的库/框架,组合使用,则可以一定程度避免这个问题

  4. Angular 我最喜欢的一个点其实是可以比较自由的自定义组件,而且 HTML 的方式很直观,解决了表达 Presentation logic 的问题。但听说 React 也能做这个?

  5. 结合前 4 条,准备看 React 了……

  6. 前端框架已经多到令人恐慌的程度了……

我可以说因为 ember 的 logo 可爱,所以我选择 ember 吗? 😄

Google 出来的东西工业化痕迹都很重。

所以 GWT, Golang, Dart 跟 Angular 都不是那种第一眼就能爱上的东西。(当然第二眼也爱不上

#19 楼 @JeskTop 搞 polymer 么?

#13 楼 @ericguo Angularjs 2.0 很可能变成第二个 python 3000,啥意思? 赶脚还是喜欢 python 2.7:)

#22 楼 @mogodb 是没法升级啊,就别说优雅了。

#23 楼 @small_fish__ 你说的是不后向兼容?

以上各位都没有提及一个重要的问题,就是『生态系统』。

我目前只用过 AngularJS,但我选择它不是因为它本身有多优秀,而是因为 Ionic,显然上面各位都在大公司,有专门设计师,所以体会不到 Ionic 对于我们这种屌丝公司来讲是多么的给力了。

楼主提及的 4 点中有 3 点我都认为有点故弄玄虚,根本不是问题:你会遇到这些坑,但这些坑与真正的坑相比根本就不是坑,比如打包,['abc', function(abc)] 就完了,谁 TMD 会说好牛 X?这么小的技能点根本就不叫技能点。但第 3 点性能问题我们的确有切肤之痛,在电脑上好好的,终端上就不行了,优化优化再优化,还是令人不太满意,最后,不怕说出来丢人,就是一个字,等!等 ionic 升级了,从 beta 13 等到 beta 14,它优化了一点点性能问题,我们应用的性能问题也就消失了。

因此,我认为未来哪家前端框架更可能胜出,取决于并且只取决于哪一个『生态系统』更加完善,比如说我们,我们的当时的需求是要快速开发一个移动应用,开源、闭源世界中转一圈,发现只有 Sencha 和 Ionic 两种选择,我们当时还没有设计师啊,设计师贵啊,你要我用什么,只能是 Angular 了啊,至于它升不升 2.0,今后兼不兼容,和我现在已经完成的应用有什么关系?现在的应用已经开发完了啊?!

OK,又有新的开发单子了,我又要选型了,我真诚的问一句:据说 React 性能极好,React 之上有类似于 Ionic 这样的框架没有?求推荐!如果有的话,我坚决要去试一试 React,前几个月的性能问题虽然已经解决到可以接受的范围内了,但真的都还有点心有余悸的感觉。

#25 楼 @xhj6 Ionic 最大的问题就是选型错误,选择了 Angular...

你可以去 Google: ionic without angular

React 的有 TouchStone.js 不过还未成熟。

#25 楼 @xhj6 其实楼上已经有提到了,所谓的生态系统,我的理解就是使用的群体,以及这些群体开发的基于 Angular 的 everything,当然也包括 ionic。这会形成一个滚雪球的效应,用的人多了,那么对于前端的各种组件就会有 Angular 的解决方案,这就促使了更多的人去用这个。

另外我不觉得会有一个像 Rails 一样打赢框架之战的 大而全 的框架。

著名的前端工程师 PPK 发表长篇文章,质疑目前最流行的前端 MVC 框架 Angular。他的一个观点是,Angular 使得前后端代码强耦合,比如下图的代码简直同以前的 asp 和 jsp 毫无区别。

servlet+jsp 在性能跑分排在第一

30 楼 已删除

#28 楼 @Victor 这个明显叫偷换概念。

这里的代码都是前端逻辑,不需要后端任何配合。换句话说:

这些代码是自成一体的。而 JSP 是后端生成的 HTML.

很明显,纯前端可以用来做 app, 维护性更好。而 JSP 则不可以。

AngularJS 会有一种眼前一亮的感觉,非常不同的哲学,但随着深入学习,以及对别的项目的了解,我越来越觉得远离 AngularJS 是对的,另外 AngularJS 显然没有成功。

#5 楼 @nightire 呵呵,你在前端花的世界,可能不少于 Ruby 本身,是么?

#25 楼 @xhj6 ionic 开发出来的应用比较占用资源?老的手机跑起来卡?

#33 楼 @mogodb 不奇怪,我本身就是前端工程师,Ruby 是我的爱好之一,也是我最喜欢的语言。

#35 楼 @nightire 原来是穿着 Ruby 马甲的前端攻城师啊,呵呵

Because now so much of people interested to learn about AngularJS. Recently i found this content via search engine. They are explain about why Angularjs is highly popular? https://blogs.agriya.com/2015/06/15/why-angularjs-is-highly-popular/

特地注册来回复,我并不认为 Angular 已经成功了。

虽然和 jquery 有区别。但是 我认为 数据绑定没意义 没价值。累赘。而且它永远不会成功。估摸也只能做做后台框架。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号