函数与函数式编程

Posted 灿烂头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数与函数式编程相关的知识,希望对你有一定的参考价值。

一、函数声明、函数表达式、匿名函数、自执行函数

函数声明

    在javascript中,有两种声明方式:一个是使用var的变量声明,另一个是使用function的函数声明

    在变量对象的创建过程中,函数声明比变量声明具有更为优先的执行顺序。因此在一个执行上下文中,无论在什么位置声明了函数,都可以在这个执行上下文中直接使用该函数。

函数表达式

    与函数声明不同,函数表达式是使用var进行声明。我们知道使用var进行变量声明,其实是进行了两步操作。如图所示:

    同样的道理,当使用变量声明的方式来声明函数时(即函数表达式),函数表达式的提升方式与变量声明的一样。

如图所示:

函数与函数式编程

    因此,由于声明方式的不同,导致了函数声明与函数表达式在使用上有一些差异。除此之外,这两种形式的函数在使用上并无不同。

    函数表达式中的赋值操作,在其他一些地方也会经常使用。如:

函数与函数式编程

匿名函数

    在函数表达式中有一个赋值的操作,匿名函数就是指没有显示进行赋值操作的函数。匿名函数多作为一个参数传入另一个函数中。如图:

函数与函数式编程

    在上面的例子中,fn的第一个参数传入了一个匿名函数。虽然该匿名函数没有显示进行赋值的操作,并且在外部执行上下文中无法引用到它,但是在fn函数内部,该匿名函数赋值给了变量bar,保存在了fn变量对象的arguments对象中。

函数与函数式编程

    由于匿名函数作为参数传入另一个函数后,最终会在另一个函数中执行,因此也常常称这个匿名函数为回调函数。

函数自执行与块级作用域

    在ES5中,没有块级作用域,因此常常通过使用函数自执行的方式来模仿块级作用域。这样就提供了一个独立的执行上下文,结合闭包,就为模块化提供了基础。函数自执行其实是匿名函数的一种应用。

函数与函数式编程

    一个模块往往可以包括:私有变量、私有方法、公有变量、公有方法。

    私有变量/方法:

    根据作用域链的单向访问,外部执行环境是无法访问内部的变量与方法的。因此可以很容易的创建属于这个模块的私有变量与私有方法。

函数与函数式编程

    公有变量/方法:

    利用闭包可以访问到执行上下文内部的变量和方法。因此,只需要创建一个闭包,将需要公开的变量和方法抛出来即可。

函数与函数式编程

    看看jQuery中是如何利用模块和闭包的。

函数与函数式编程

    在使用时,直接执行了构造函数,因为在jQuery的构造函数中通过一些手段,返回的是jQuery的实例,所以就不用每次用的时候自己new了。

二、函数参数传递方式:按值传递

    当值作为函数的参数传递进入函数内部后,实际上是保存在了函数的变量对象中,这个时候相当于发生了一次复制。如下图所示:

函数与函数式编程

    再看一个例子:

函数与函数式编程

三、函数式编程

    当使用一个函数时,通常情况下就是将一些功能、逻辑等封装起来。例如想要计算一个数组中所有子项目的和。

函数与函数式编程

    如果不通过函数封装的方式,那么每次想要实现这个功能时,就不得不重新写一次类似的代码。这就导致会有越来越多的重复代码。

    函数式编程有助于我们更好的去封装一个函数。

    再看一个例子:

函数与函数式编程

    使用命令式编程思维的问题在于,当想要找出另外一个数组中符合某个要求的所有子项时,不得不把同样的逻辑再写一次。这样做不利于后期的维护。

    而使用函数式思维编程将功能封装之后,实现同样的功能,只要写一行代码即可。如果在未来需要变动或者修改,只需要对封装的方法进行调整就可以了。有利于后期的维护。

    函数式编程的几个特征:

    ①函数是第一等公民

    函数可以赋值给其它变量,也可以作为参数传入另一个函数,也可以作为别的函数的返回值。

函数与函数式编程

    可以用一个简单的例子来验证一下:

函数与函数式编程

    ②只用“表达式”,不用“语句”

    “表达式”是一个单纯的运算过程,总是有返回值;“语句”是执行某种操作,没有返回值。函数式编程的要求是只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

举个例子来了解一下:

    ③纯函数

    纯函数:相同的输入总会得到相同的输出,并且不会产生副作用的函数。

    所谓的“副作用”,指的是函数内部与外部互动(最典型的就是修改全局变量的值),产生运算以外的其它结果。

    函数式编程强调没有“副作用”,意味着函数要保持独立,所有的功能就是返回一个新值,没有其它行为,尤其是不能修改外部变量的值。

举个例子来了解:

    getLast1和getLast2虽然都能够获得数组的最后一项,但是getLast2改变了原数组。getLast2的封装是非常糟糕的。

    ④闭包

    ⑤柯里化

   


以上是关于函数与函数式编程的主要内容,如果未能解决你的问题,请参考以下文章

函数与函数式编程

python中的函数式编程与装饰器

函数式编程与响应式编程

活动预告Haskell与函数式编程

函数式编程与面向对象编程[关闭]

初识函数式编程与函数式接口