用函数式编程对JavaScript进行断舍离
译者按: 当从业20的JavaScript老司机学会函数式编程时,他扔掉了90%的特性,也不用面向对象了,最后发现了真爱啊!!!
为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改。另外,本文版权归原作者所有,翻译仅用于学习。
我和JavaScript
从1997年网景的Navigator 3浏览器开始就开始使用JavaScript。当时,JavaScript还只能做一些很简单的事情。我记得最酷的就是用JavaScript实现mouseover特性,在那个时候已经算得上是高科技了!当鼠标移过去之后,文本内容就神奇的改变了。因为当时都是pre-DHTML,你根本不需要隐藏或则显示DOM元素。
关于DHTML(以前的 DHTML 如今是不是也算前端?):
DHTML是Dynamic HTML的简称,就是动态的html(标准通用标记语言下的一个应用),是相对传统的静态的html而言的一种制作网页的概念。所谓动态HTML(Dynamic HTML,简称DHTML),其实并不是一门新的语言,它只是HTML、CSS和客户端脚本的一种集成,即一个页面中包括html+css+javascript(或其它客户端脚本),其中css和客户端脚本是直接在页面上写而不是链接上相关文件。
在那个时候,JavaScript的演化很慢,主要应用在表单验证。因此,不像今天这么火爆,并没有引起太多的关注。可以说只是一个锦上添花的附加物,你需要确保在浏览器禁用JavaScript之后,你的应用依然可以正常使用。再往后,框架一个接着一个出现:jQuery,Knockout, Angular, React, Vue, 等等。
同样,JavaScript也在加速演化。我们才使用ES6不久,现在人们几乎已经跳过ES7,开始讨论ES8了。
并且,我们有很多替代品,比如TypeScript,CoffeScript,ClojureScript, ELM,等等。
我们已经被太多的框架和语言所淹没,很难去跟踪和掌握所有的语言和框架。
错误路线
当JavaScript逐渐成熟,面向对象编程(OOP)的概念也渗入进来,而且我曾经很喜欢。
我开始尝试所有不同的方法来创建类,我最终也可以正确的使用继承。我对自己说:JavaScript开始真的像一个语言了!
但是,直到多年以后我发现OOP是JavaScript引入的最糟糕的一个设计!
我尝试将我对C#的理解带入到JavaScript中去。一开始充满期待,但是后来发现真的太复杂,太烧脑了。
这主要是因为JavaScript的原型继承和C#不一样,我已经习惯于每天编写类似于console.log(this)
这样飘逸的代码。但是现在呢?如果我一不小心没按照规则来,那将会给我带来噩梦。私有方法和私有值必须要在名字前面加上下划线,甚至必须用闭包来保证私有性。
因此,不仅OOP导致了很多问题,同时也由于添加OOP带来了很多新的问题。
函数式编程
一开始我并不理解。我可以阅读并理解这些用函数式编写的代码,但是不知道为什么!最终,我强迫我自己去学习它。我在在线教育网站EDX免费学习了函数式语言的入门课程,然后尝试把这些技术运用到JavaScript中去。
函数式语言给了我一个全新的视角,让我从一个完全不同的方式去看待编程。
一开始会感到不自然,需要时间去适应。所有的定义都是基于函数,值不可更改,无状态。我用函数式的思维去解决问题。因为不熟悉,我花了更长的时间去学习。渐渐地,我熟练掌握了使用函数式的方法去编程。并且,我也知道所有代码这样编写的内在含义。
我的代码更加简洁了,而且容易复用。渐渐的,我以前使用的那些语言特性从代码中消失了,我的代码看上去完像是用另一个语言编写。我还在用JavaScript吗?
1. 不再使用var
我用const
替代了var
。通过函数式的设计,我的函数都是纯(pure)的。不会再去对一个变量进行值的变更操作,同样也是为了确保不会对其操作。
我会检查代码确保每一个var
,甚至let
,所有声明都使用const
。
2. 没有for循环
在学习程序语言的时候,我们一开始就会学到for
循环。但是自从学习了函数式编程,我将for循环都改成了使用filter, map和reduce来实现。对于那些需要一些额外计算的需求,我会使用递归或则第三方库比如lazy.js
。
在此,推荐我的另外一篇专门介绍for循环博客:Rethinking JavaScript: Death of the For Loop
如今我的代码里面完全没有for循环了,如果你看到了,告诉我我会把它消除。
3. if也可以被简化
我开始停止在if里面编写大块大块的代码。我将里面的逻辑抽取出来单独放在一个函数中。这样,我们就可以将if用三元算子(a?b:c)来简化。
在此,推荐我的另外一篇专门介绍if博客:Rethinking JavaScript: The if statement
如今我的代码里面几乎没有if语句。为了方便其他开发者理解我的代码,我很少使用它。
4. 和switch说拜拜
同样,我也不喜欢用switch,而是寻找一个函数式的写法。
推荐我的博客: Rethinking JavaScript: Eliminate the switch statement for better code
我也很喜欢用Ramda的cond算子来替代swtich。
5. 不在担心this
对的,你没有听错!我们也可以完全消除this
。
函数式的JavaScript可以让你完全抛弃使用烦人的this
现在只有数据和函数,甚至数据不过是函数的一种特殊表达形式,你再也不需要this了。我开始将对象理解为函数式语言中状态(state)和函数。我甚至不需要把状态或则函数和对象绑定到一起,就像OOP中那样。
我写了一篇博客专门介绍如何解耦: Functional JavaScript: Decoupling methods from their objects
面向对象的设计不是必须的
现在往回看,我发现面型对象编程带来的复杂度真的是不必要的。我可以使用函数式语言实现同样的功能,完成相同的任务。而且,代码更加轻简,因为不在需要将这些复杂的对象传来传去。只有数据和函数,而且因为函数没有和对象绑定,更加容易复用。我不在需要担心传统的原型继承带来的所有的问题,JavaScript设计的并不好。
JavaScript缺乏私有、公有、内部或则被保护这类访问控制器也不再是一个问题。访问控制器是用来解决由于引入面向对象编程而设计的。在函数式的JavaScript中,这些问题不复存在。
总结
我的代码现在看上去完全不同。它包含了很多纯函数,我将它们做成不同的ES6模块。这些函数可以被使用来构建更加复杂的函数。很大一部分函数都是很简单的一行lambda表达式。
现在我看待软件的思维也变了:输入是一个数据流,然后程序作用到该数据流上对数据进行各种操作,然后返回新的数据。
函数式设计对程序语言的影响以及无处不在,C#中的LINQ就是一个最佳的例子。同样Java 8也引入了函数式语言的特性。
关于Fundebug:
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/09/13/how-i-rediscovered-my-love-for-js/
用函数式编程对JavaScript进行断舍离的更多相关文章
- 快速入门函数式编程——以Javascript为例
函数式编程是在不改变状态和数据的情况下使用表达式和函数来编写程序的一种编程范式.通过遵守这种范式,我们能够编写更清晰易懂.更能抵御bug的代码.这是通过避免使用流控制语句(for.while.brea ...
- 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 引言&前言
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 译者团队(排名不分先后):阿希.blueken.brucec ...
- 全本 | iKcamp翻译 | 《JavaScript 轻量级函数式编程》|《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson - <You-Dont-Know-JS>作者 译者团队(排名不分先后):阿希.blueken.bruc ...
- JavaScript:了解一下函数式编程
一.简介 在JavaScript中,函数就是第一类公民,它可以像字符串.数字等变量一样,使用var修饰并作为数据使用.它可以作为数值.可以作为参数.还可以作为返回结果.可以说JavaScript就是函 ...
- 一文带你了解JavaScript函数式编程
摘要: 函数式编程入门. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 函数式编程在前端已经成为了一个非常热门的话题.在最近几年里,我们看到非常多的应用程序代码库里大量使用着函 ...
- 让JavaScript回归函数式编程的本质
JavaScript是一门被误会最深的语言,这话一点不假,我们看下它的发展历史. 1995年,Netscape要推向市场,需要一门脚本语言来配套它.是使用一门已有的语言,还是发明一门新的语言,这也不是 ...
- JavaScript学习(3):函数式编程
在这篇文章里,我们讨论函数式编程. 什么是函数式编程?根据百度百科的描述,“函数式编程是种编程典范,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 λ 演算(lambda calculus). ...
- JavaScript 与函数式编程
原文:https://bethallchurch.github.io/JavaScript-and-Functional-Programming/ 译文:http://www.zcfy.cc/arti ...
- javascript 函数式编程
编程范式 编程范式是一个由思考问题以及实现问题愿景的工具组成的框架.很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等. 函数式编程 ...
随机推荐
- Android WebView 实现网页缩放
需要对WebView设置的内容如下: //缩放开关,设置此属性,仅支持双击缩放,不支持触摸缩放 mWebView.getSettings().setSupportZoom(true); //设置是否可 ...
- 还在使用SimpleDateFormat?
阅读本文大概需要 3.2 分钟. 前言 日常开发中,我们经常需要使用时间相关类,想必大家对SimpleDateFormat并不陌生.主要是用它进行时间的格式化输出和解析,挺方便快捷的,但是Simple ...
- 如何解决微信小程序界面适配问题-引用-生命周期回调函数-优化机制-样式引入
如何解决微信小程序界面适配问题 .wxss page{ height: 100%; width:750rpx; } this.setData({ imageWidth: wx.getSystemInf ...
- lua模块demo(redis,http,mysql,cjson,本地缓存)
1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...
- HBase之HRegionServer启动(含与HMaster交互)
在我的博文<HBase——HMaster启动之一>.<HBase——HMaster启动之二>中已经详细介绍过HMaster在启动过程中调用的各种方法.下面,单就HRegionS ...
- Mac idea激活
感谢https://blog.csdn.net/HALEN001/article/details/81137092 1.下载IntelliJ IDEA 2018.2.2版本和破解补丁Jetbrains ...
- sql server 性能调优之 资源等待PAGELATCH
一.概述 在前几章介绍过 sql server 性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql server要和磁盘作交互的时候,所以加个IO两个字.这次来介绍PAGE ...
- RocketMQ源码 — 五、 主要feature及其实现方式
RocketMQ的主要特点以及实现方式 单机支持1万以上持久队列 所有数据单独存储到一个CommitLog,完全顺序写,随机读 在一个broker上一个DefaultMessageStore管理一个c ...
- Python作用域详述
作用域是指变量的生效范围,例如本地变量.全局变量描述的就是不同的生效范围. python的变量作用域的规则非常简单,可以说是所有语言中最直观.最容易理解的作用域. 在开始介绍作用域之前,先抛一个问题: ...
- 解读经典《C#高级编程》第七版 Page68-79.对象和类型.Chapter3
前言 新年好,本篇开始进入第三章,<对象和类型>,深刻理解C#的对象,对于使用好.Net类库非常重要. 01 类和结构 从使用角度看,结构和类的区别很小,比如,将结构定义转换为类,只需要将 ...