谈谈学习
09 September 2015

一个程序员的学习能力、接受新事物的能力绝对是非常重要的影响人的发展的一个因素,特别是前端程序员。最近有看一本2011年的书《JavaScript DOM编程艺术》,目的只是想熟悉一下自己的短板-原生js dom操作,大家都推荐这本。看了100多页的感觉就是看历史书一样,那个年代不是所有浏览器都支持javascript,兼容性多是指如何在不支持js的浏览器上优雅退化,绑事件还都是onEvent的方式…3年过去了,变化太大了,导致3年前的书都没法看下去了。

新兴的东西更是多,先不说html5 API中如webSocket、canvas之类以及css3的动画(前一阵看到张鑫旭老师1年前用css3写出了轮播图,非常流畅),nodejs的兴起带来了前端的模块化,AMD、CMD模式,requirejs、seajs的代表库。手机的兴起带来了单页面应用和web app,backbonejs,angularjs,reactjs这些框架/库更是与传统的库差别很大,刚学时可能无法适从,因为他们不仅是语法糖的实现,更是编程思想的变格。开发上从纯手工化到工具的兴起,bower、gulp、grunt等等等。小小的前端和js从写页面到nodejs写后台到react native写app。我相信还有很大的一部分前端没有跟上这些发展。

最近在知乎上看到徐飞老师的一句话:

这几年我看到不少人,从Backbone追到Angular,又追到React,每次出一个比较新的东西都立刻追进,你问他:这个好在哪里?他从网上复制几句话,然后语焉不详,再追问下去,就是:反正我用的东西就是好。

说中了多少 少年,还是积极向上热爱学习的少年,估计还有一大部分少年这3个都没接触。

最近我也在学习react,初衷很简单,太火了,我想看看这么火的东西的先进之处。我很乐于追求新东西,倒不是赶时髦,新东西总是有它的适用场景和先进之处,我总是想了解这些先进的技术和思想。

对于前端新库和框架的学习,我都是首先看他的设计思想和设计模式,关注适用场景。设计思想体现的是每个库的特色和存在的必要性,然后你再学习具体的api和demo时,你会发现就是他的原始的设计思想指导着你去这么用它。理解了设计思想,你才能它适用与什么场景,该怎么用它。有个和我一起用angular写项目的学弟,看到他的代码确实有点后悔没早点让他研究思想的,因为对于用户操作带来页面的动态内容时,他还是从dom操作触发,而不是从数据源出发,这样人家辛辛苦苦搞出的双向绑定却没被正确用上。

由于技术的发展,规范的变迁,浏览器环境的变迁,一个框架和库可能被淘汰被取代,但是那些背后的设计思想将很久都不会落后。

我理解的前端说到底,首先是底子够硬,能徒手写的一手优雅的js,而不要闹出那么多笑话:你在公司项目里面看到过哪些操蛋的代码,能使用最恰当的css。然后可能一开始我们都是使用别人的库,这并没有什么坏处,但是不能只是学学api,知道怎么写,这样库和框架一直在翻新,你每天都像重头学习一样。你要先了解其设计模式和思想,还要又能力透过封装好的api看出底层的js实现的到底是什么,你可以推测,可以查网上大牛们的研究结论,最好的是自己看源码(看源码方面我很汗颜,几乎没看过。。。能力还不够,看的吃力)。

用过framework7,学到的是mvc分层的思想,每一层都专注于自己的工作,不混搭,配合requirejs,让依赖关系变得清晰,且再也不污染全局变量了。

用过angular,学到的是mvvm,viewmodel是个神奇的存在,双向绑定带来的是福音,因为dom操作是耗性能的,而大多数前端并没有掌握高效操作dom的技能。双向绑定让我们的关注点从dom移到了数据源上,同样的譬如说评论区添加了一条评论,以前我们想的是动态添加一段包函数据的dom进页面,即使用framework7也顶多只能暴力的重新渲染一遍添加了新数据的模板。而angular让我们把注意力从视图和dom中移出,dom依赖数据的动态更新框架帮我们做了,而我们应该相信写angular的人是有能力高效操作dom的。我们只要向表示评论的数据变量里添加一条新数据,视图就自动更新添加了一条新评论。然后angular的contoller、service、directive、filter更是各司其职,高效组合。contoller负责主要的业务代码,组合其他部分,这是每个页面独有的,service是单例,负责如与后台数据交互和一些只与js相关的可复用的功能性代码。而directive是angular核心,每个directive都像是一个组件,包含相关的html和js,复用性特别高,你随时可以拿它到其他项目中组合,所需的代码量非常小,仅仅是加个依赖。filter是过滤器,你可以为你项目中很特色的转换写filter。还有依赖注入这个特色,不仅防止了全局变量污染,也是用一种不同于requirejs的方式,让依赖变得清晰,每段代码只需要自己依赖的模块。angular带给我最深的是知道什么是组建,如何复用,还有从立足于数据而不是dom。

最近刚看react,说不出什么高大上的东西。他不同于前面2个,它有点类似与angular的directive部分,强调的是组件化,而且不同于angular以功能区分代码,而是以功能界面划分代码块,一个页面会被划分成很多个组件,最难得是你有划分好的组件的思想,每个组件要能复用,只关注自己独立的功能。组件和组件之间循环嵌套,以this.props传递变量,this.ref传递标签属性。最有特色的是state,react首创了单向的状态机,每个state下的变量都在整个组件中统一,且是单向绑定,目的是为了避免多处操作它带来的状态混乱(譬如angular需要$apply和$digest来解决),组件之间通过this.state传递状态变量。还有一个特色是virtual DOM,据说非常高效,因为他没有直接操作dom,操作的是virtual DOM,而virtual DOM存储在与内存中,速度非常快,每次数据变化都是刷新virtual DOM,然后跟上一版的virtual DOM对比,在通过diff算法只映射变化的dom部分到真正的dom树上,而且jsx允许在node服务器渲染,这既解决了SEO的问题,也减少了浏览器渲染的压力。这个模式是angular没有的。我觉得非常新颖。至于组件化,暂时的感受是特别繁琐,因为拆分的太多,嵌套的太多,而且我对于这种牵涉到state、props的组件能够有多大的复用可能和每个页面拆的那么多的组件的复用需求表示怀疑。react的语法糖开始也会有点不习惯。相比angular,由于react只是在视图层,且不是真正的框架,而是一种模式,学习起来成本比较高。以上感悟仅是2天学习后的感悟,可能不准确。

对于新事物,关注设计思想和模式。