05-那又如何
13.4 那又如何
至此大家已经见识了函数的三种不同形式(子程序、有返回值的子程序,以及纯函数)。是时候停下来问问自己,如此区分的意义何在?
本章的重点不是解释JavaScript语法,而是思考为什么。为什么需要函数?用函数来定义子程序就是答案之一:为了避免重复代码。因为子程序可以帮助打包常用功能,多么明显的好处。
通过封装代码来避免重复是一个如此基础的概念,以至于它都有自己的缩略词:DRY(don’t repeat yourself,不要重复你自己)。虽然从语言层面看来可能有问题,但会发现人们将这个缩略词当做形容词来描述代码。比如,“这段代码可以更DRY一些。”如果有人这样说,他们其实是想说明代码中写了没必要的重复代码。
纯函数稍微难以理解一些,因为它是以一种更抽象的方式来回答“为什么”这个问题的。一个可能的答案是“因为它们使编程更像数学!”不过这也许会引发另一个问题:“为什么编程要像数学呢?这样做有什么好处?”一个更好的回答可能是“因为纯函数让代码更易于测试,更轻量、可读性更高”。
当一个函数在不同情况下返回不同的结果或者会产生副作用,那么称之为上下文相关。举个例子,如果有个函数,它会产生副作用,但是确实有用,当把它从一段程序移到另一段程序后,它就可能失效了。或者更糟糕的是,99%的时间里它能正常工作,但在剩下的1%时间里造成严重的漏洞。任何开发人员都知道,间歇性的漏洞是最可怕的:它们可以长时间潜伏在系统中,一旦爆发,定位这些漏洞就犹如大海捞针。
如果大家想知道本书是否推荐纯函数,作者只能说:是的,应该始终优先使用纯函数。这里用了“优先”这个词,是因为有时候用一个带有副作用的函数会更简单。如果你是个编程初学者,可能会更倾向于经常这样做。并不是说不能这么做,不过更希望大家能停下来思考一下,试试能否想出一种使用纯函数的替代方式。这样一来,随着时间的推移,你会发现自己很自然地倾向于使用纯函数。
在第9章中讲过的面向对象编程提供了一种范式,它允许通过严格控制副作用的作用域,从而来以一种受控和合理的方式使用它。
通过封装代码来避免重复是一个如此基础的概念,以至于它都有自己的缩略词:DRY(don’t repeat yourself,不要重复你自己)。虽然从语言层面看来可能有问题,但会发现人们将这个缩略词当做形容词来描述代码。比如,“这段代码可以更DRY一些。”如果有人这样说,他们其实是想说明代码中写了没必要的重复代码。