介绍
先简要介绍一下面向对象和函数式编程。
两者都是编程范式,在允许和禁止的技术上有所不同。
有仅支持一种范式的编程语言,例如 Haskell(纯函数式)。
还有支持多种范式的语言,例如 JavaScript,你可以用 JavaScript 编写面向对象的代码或函数式代码,甚至可以将两者混合。
创建项目
在深入探究这两种编程范式之间的差异之前,先创建一个阶乘计算器项目。
首先创建所需的所有文件和文件夹,如下所示:
接下来在 内创建一个简单的表单。
为了使界面看上去不那么丑陋,我们把 bootstrap 作为 CSS 框架。
如果在浏览器中显示这个 HTML,应该是这样的:
现在这个表单还没有任何操作。
我们的目标是实现一种逻辑,在该逻辑中你可以输入一个最大为 100 的数字。单击“Calculate”按钮后,结果应显示在 中。
下面分别以面向对象和函数式的方式来实现。
函数式实现
首先为函数式编程方法创建一个文件。
首先,需要一个在将此文件加载到浏览器时要调用的函数。
该函数先获取表单,然后把我们需要的函数添加到表单的提交事件中。
首先声明一个名为 的函数。
这个函数有两个参数,第一个是要在 HTML 中查找的标签,第二个是要绑定到 的 的函数。
接下来,通过传入 和函数名 来调用此函数。
标签前面的 表明我们正在寻找 HTML 中的 属性。
如果现在尝试运行该代码,则会抛出错误,因为在任何地方都还没有定义函数 和 。
因此,首先在 函数前面定义 ,如下所示:
这个函数非常简单,只返回通过传入的标记找到的 HTML元素。但是稍后我们将重用此功能。
现在添加 函数来创建核心逻辑。
把事件传回后立即调用 。
这将阻止 Submit 事件的默认行为,你可以试试不调用 时单击按钮后会发生什么。
之后,通过调用 函数从输入字段中获取用户输入的值。在得到数字后,用函数 计算阶乘,然后通过将结果传递给函数 将结果展示到页面。
如果该值的格式不正确或者数字大于 100,将会抛出错误并弹出 alert。
下一步,创建另外两个辅助函数: 和 ,并将它们添加到 函数后面。
这两个函数都使用我们的 函数。这种可重用性是为什么函数式编程如此有效的一个原因。
为了使它更加可重用,可以在 上添加名为 第二个参数。
这样就可以动态设置应该显示结果的元素。
但是在本例中,我用了硬编码的方式。
接下来,在 前面创建 函数。
接着创建一个名为 的函数来验证参数 是否为空且不大于 100,且类型为 number。如果检查通过,就调用 函数并返回其结果。如果没有通过,则抛出在 函数中捕获的错误。
在这个函数中,用 来确定要执行的验证范式类型。这只是一个简单的值验证。
然后在 声明的前面添加实际的 函数。这是最后一个函数。
最终的functional.js文件下所示:
在这种方法中,我们专门处理函数。每个函数都只有一个目的,大多数函数可以在程序的其他部分中重用。
对于这个简单的 Web 程序,使用函数式的方法有些过分了。接着将编写相同的功能,只不过这次是面向对象的。
面向对象的实现
首先,需要将 文件的脚本标签中的 更改为以下内容。
然后创建 oop.js 文件。
对于面向对象方法,我们要创建三种不同的类,一种用于验证,一种用于阶乘计算,另一种用于处理表单。
先是创建处理表单的类。
在构造函数中获取 和 并将其存储在类变量(也称为属性)中。之后将方法 添加到 中。在这种情况下需要把类的 绑定到方法。如果不这样做,将会得到一个引用错误,例如调用 将会是 。之后以事件为参数创建类方法 。
该方法的代码看起来应该有点熟悉,例如 if 语句检查输入值是否有效,就像在 函数中所做的那样。 是对我们仍然需要创建的 类中的静态方法的调用。如果使用静态方法,则无需初始化对象的新实例。验证通过后创建 类的新实例,传递输入值,然后将计算的结果显示给用户。
接下来在 类 前面创建 类。
这个类内部的所有内容都是静态的,所以我们不需要任何构造函数。
这样做的好处是不需要在每次使用它时都初始化该类。
与 函数与我们的 几乎完全相同。
接下来在 类的后面创建 类。
在初始化这个类的实例后,我们获得 resultElement 并将其存储为属性以及我们传入的数字。
之后调用方法 并将其返回值存储在属性中。 方法包含与 functional.js 中的 函数相同的代码。最后是 方法,该方法将结果元素的 innerHTML 设置为现实计算出的阶乘数。
完整的oop.js文件如下所示。
我们创建了三个类来处理程序的三个不同的功能:
验证: 类
阶乘处理: 类
表单处理: 类
总结
两种方法都是编写代码的有效方法。我喜欢在自己不同项目中尝试最有效的方法。在很多情况下,甚至不可能如此清晰地分离这两种范式。
希望这篇文章可以使你对不同的编程方法有一个基本的了解。