函数

87 阅读4分钟
  • 面向函数编程(functional program):即把计算过程封装成独立的院子方法,方便调用的想法
  • 函数的特点:函数是第一等公民,可以作为参数也可以作为返回值,也可以赋值给参数
  • 高阶函数:把function作为参数或者返回值的函数都叫做高阶函数

函数的执行过程

  • (1) 全局执行环境:指运行再最外层的执行环境,在web中全局执行环境被认为是window对象,所有在全局环境中的变量和函数都是对象的属性和方法
  • (2)执行环境:在作用域下创建属性方法的环境,在执行完所有代码后,该环境就回被销毁,被回收掉,每个函数都有自己的执行环境,
  • (3)执行环境栈:依次放置执行环境的栈(Call stack),执行环境下函数执行完成就移除执行栈,并被js gc回收,并把执行权限交给下一个执行环境函数的环境就会被推入“环境栈”中。函数执行完后,栈将其弹出并销毁变量对象,然后把控制权返回在给之前的执行环境。如果内执行环境的变量对象,被外部执行环境引用,那么内部环境变量对象就无法被销毁(如:闭包)。
  • (4)变量对象:每个执行环境中定义的变量和函数都赋值给变量对象,
  • (5) 活动对象:指当前正在执行执行环境的变量对象
  • (6) 作用域链:是一个链表,存储着与执行环境相关的变量对象和arguments,可以通过scope属性查看变量对象列表
  • (7) 作用域链的访问顺序: 如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。如果整个作用域链上都无法找到,则返回undefined。

image.png

闭包

  • 能够读取父级函数内部变量的函数
  • (1) 在构造函数体内定义另外的函数作为目标对象的对象,这个函数对象可以反过来引用外部函数的变量,这使得只要目标 对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目 标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新 的值,和上次那次调用的是各自独立的。
  • (2)特点 :让外部访问函数内部变量成为可能; 局部变量会常驻在内存中; 可以避免使用全局变量,防止全局变量污染; 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

函数柯里化

  • (1)把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
  • (2)代码实现:返回值始终是一个函数,需要被执行
Function Currying(fn,args){
   Var _this = this;
var len = fn.length;
Var args = args||[];
   Return function(){
    Var _args = [].slice.call(arguments);
    [].push.apply(args,_args);
    If(_args.length < len) 
        Return currying.call(_this,fn,_args)
    Reurn fn.apply(this,_args);
    }
}

纯函数

  • (1)一个函数的返回值只依赖于它的参数,且再执行过程里面没有副作用(即只对执行过程进行封装的喊出)
  • (2) 特定:1、函数的执行过程中没有任何的副作用,2、返回结果只依赖于她的参数
  • (3) 副作用:配置文件,IO,全局变量等

函数组合

(1)有若干个函数组合成一个新的函数,同时完成数据的传递,主要解决洋葱代码的出现,可通过reduce函数实现

function composeFunctions(...fns) {
    return function (arg) {
        return fns.reduce((a, fun) => fun(a), arg)
    }
}

函子

  • (1) Functor(函子)遵守一些特定规则的容器类型或者数据编程协议;具有一个通用的map方法,返回新实例,这个实例和之前实例有相同的规则;具有结合外部的运算能力;
  • (2)函子类型: MayBe函子:处理空值 Either函子: 用于处理异常 IO函子: IO函子可以把不纯的操作储存到_value,延迟执行这个不纯的操作,惰性执行,包装当前的操作。把不纯的操作交给调用者处理