JavaScript编程基础 – 函数进阶
JavaScript Programming Essentials – Perfect Functions
“函数的第一条原则是要小,函数的第二条原则是要更小。“ – 罗伯特.C.马丁
前文讲述过函数多取决于数学的函数概念,以此来定义JavaScript编程语言的函数,从而实现函数式编程。
依据传统数学函数的定义,变量x和函数值y的相互关系始终遵循以下这个公式:
y = f(x)
至于输入的x如何变成y,却有诸多种方法。
尽管前文从不同角度介绍了函数,但是那些是传统的JavaScript函数思想,也就是说,随着ECMAScript标准的演进,这些东西都有可能产生变化。
本文简要介绍JavaScript函数在ECMAScript 2015,也就是ES6规范下的新的变化和新的功能,以便使读者了解函数式编程取得的新的进展能够更加有效地服务于软件服务。
1. 调用名称的函数
简而言之,函数是一段通过其名称被调用的代码,并且,它可以传递参数和返回值。
假设有一个简单函数,只返回它的参数传递的值,不进行任何复杂计算。
示例代码如下:
var simple = (a) => {return a} // 一个最简单的函数
console.log(simple(5)) // 用函数的名称调用
运行结果如下图:
2. 调用方法的函数
作为一个简单的方法,用名称和其关联调用,是另一个函数示例,代码如下:
var obj = {simple : (a) => {return a }}
obj.simple(5) // 用其名称及其关联对象调用
运行结果如下图:
3. 引用透明性
基于纯粹的函数定义,所有的函数对于相同的输入,都将返回相同的值。函数的这个属性被称为 引用透明性 (Reference Transparency)。
以下定义几个简单函数,分别按照传原值、传加法值、传乘法值返回结果;无论传入什么作为输入,最终都会按规则把它返回。
var identity = (i) => {return i}
const add = (x, y) => x + y
const multiply = (x) => x * 5
执行结果如下图:
不难看出,JavaScript的表达式可以替换为它的计算值,这就是引用透明性。
由于函数会为给定的输入,返回相同的值,实际上可以缓存它。
比如,有一个阶乘函数factorial,用来计算给定数值的阶乘,大家都知道5的阶乘等于120(54321 = 120),那么用户第二次调用函数factorial,结果如何呢? 答案仍然是120, 如下代码:
function factorial(n) {
let ans = 1;
if(n === 0)
return 1;
for (let i = 2; i <= n; i++)
ans = ans * i;
return ans;
}
执行结果如下图所示:
4. 命令式方法
创建一个数组,用for循环遍历它的数组元素,代码执行如下:
以上这段代码运行良好。但为了解决问题,需要准确地告知程序应该“怎么“做。在本中,代码告诉编译器获得数组长度,遍历数组,用索引获取每一个数组元素等。
这种方法称之为 “命令式“解决方案。命令式编程主张告诉编译器”怎么“做。
5. 声明式方法
另一种编程思路,是告诉编译器做“什么“, 而不是”怎么“做或者”如何“做。
这种方法称之为 “声明式“解决方案。声明式编程中,”怎么“做的部分被抽象到函数中。
示例代码如下,用内置的forEach函数遍历数组并打印输出它:
var array = [1, 2, 3]
array.forEach((element) => console.log(element))
执行结果如下图所示:
用函数方法处理循环问题
如果需要遍历一个数组,并且将结果打印输出到控制台,可用以下代码来实现:
var array = [1, 3, 5, 7, 9]
for (i = 0; i < array.length; i ++)
console.log(array[i])
执行结果如下图:
函数式编程中,将操作抽象成函数;如果这样做的话,需要把操作抽象为函数,以便在需要的时候能够重用,这比每次都告诉函数“怎样“去遍历要好。
6. 存储函数到变量
函数就是数据;可以把它存入一个变量。类似以下的代码:
let fn = () => {}
console.log(typeof fn)
执行结果如下图所示:
其功能无论如何增强,都验证了一个事实,就是函数的结果除了像返回值那样,还可以存储到(赋值)一个变量。
7. 传递函数
下面的函数示例,告诉我们接受一个参数并将参数的类型打印输出到控制台:
var tellType = (arg) => {
console.log(typeof arg)
}
tellType("Welcome")
传递字符串“Welcome”作为参数,执行结果如下图:
可以看到,返回类型为string,如果增加传递几种参数,传递结果如下图:
返回类型分别为boolean, number和string.
另一个代码如下,将判断如果参数是函数,那么该函数tellType就执行它。
var tellType = (arg) => {
if(typeof arg === "function") {
arg()
} else {
console.log("The passed data is:" + arg)
}
}
var dataFn = "Welcome"
tellType(dataFn)
可以看到,通过传递dataFn(一个字符串变量)来执行tellType; 这样,成功地将dataFun传递给另一个函数tellType, 而tellType执行了传入的函数。
执行结果如下图所示:
函数式编程是JavaScript语言的显著特征,今后有机会将继续研究它的高级特性。
技术好文陆续推出,敬请关注。
喜欢就点赞哈。😊