1-函数式编程 基础概念 柯里化(01-01-01)

148 阅读6分钟

函数

函数概念

1、函数是一等公民

  • 函数可以存在变量中
  • 函数可以作为返回值
  • 函数作为参数

2、高阶函数

  • 可以把函数作为参数传给另一个函数
  • 可以把函数作为另一个函数的返回结果

3、apply和call的区别

  • Person.call(this,name,age) 参数是一个数组
  • Person.apply(this,[name,age]) 参数第二个是一个数组
  • call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象
  • call和apply就是js函数自带方法,挂在Fucntion.prototype上

4、使用高阶函数的意义

  • 抽象可以帮我们屏蔽细节,只需要关注与我们的目标
  • 高阶函数是用来抽象通用的问题

5、两种编程方式

  • 面向对象编程的思维方式:把现实世界中的事物抽象成程序世界中的类和对象,通过封装、继承和 多态来演示事物事件的联系
  • 函数式编程的思维方式:把现实世界的事物和事物之间的联系抽象到程序世界(对运算过程进行抽 象)

6、使用高阶函数的意义

  • 抽象可以帮我们屏蔽细节,只需要关注与我们的目标
  • 高阶函数是用来抽象通用的问题

7、forEach与map的区别与用法

  1. 相同点:
  • 都是循环遍历数组中的每一项
  • 每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)
  • 匿名函数中的this都是指向window
  • 只能遍历数组
  1. 不同点
  • map()会分配内存空间存储新数组并返回,forEach()不会返回数据,
  • forEach()允许callback更改原始数组的元素。map()返回新的数组。

Tips:

  1. 关于中断循环:for循环是可以中断循环(利用break语句或return语句),但forEach不可以中断循环。
  2. for循环中会等异步调用完成后再执行后面的语句 forEach中包含异步调用时会直接执行后面的语句 如果循环中包含了异步调用、并且循环后的同步操作调用了遍历后的结果,应该使用for循环代替forEach

8、闭包

  • 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员
  • 闭包的本质:函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能释放,因此内部函数依然可以访问外部函数的成员

9、js中的堆内存与栈内存

在js引擎中对变量的存储主要有两种位置,堆内存和栈内存。 和java中对内存的处理类似,栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null,**以及对象变量的指针,这时候栈内存给人的感觉就像一个线性排列的空间,每个小单元大小基本相等。 而堆内存主要负责像对象Object这种变量类型的存储。

10、内存分配和垃圾回收

  • 一般来说栈内存线性有序存储,容量小,系统分配效率高。而堆内存首先要在堆内存新分配存储区域,之后又要把指针存储到栈内存中,效率相对就要低一些了。
  • 垃圾回收方面,栈内存变量基本上用完就回收了,而推内存中的变量因为存在很多不确定的引用,只有当所有调用的变量全部销毁之后才能回收。

11、普通函数、匿名函数

  1. 普通函数需要使用函数名进行标识,匿名函数不需要使用函数名进行标识; 普通函数的函数体中可以有多条语句,匿名函数只能是一个表达式;
  2. 普通函数可以实现比较复杂的功能,匿名函数只能实现比较单一的功能; 普通函数可以被其它程序使用,匿名函数不能被其它程序使用。 匿名函数,仅在调用时,才临时创建函数对象和作用域链对象;调用完,立即释放,所以匿名函数比非匿名函数更节省内存空间

12、纯函数

  • 纯函数:相同的输入永远会得到相同的输出,而且没有任何可观察的副作用

13、数组转字符串

需要将数组元素用某个字符连接成字符串,示例代码如下:

var a, b;
a = new Array(0,1,2,3,4);
b = a.join("-");

字符串转数组 实现方法为将字符串按某个字符切割成若干个字符串,并以数组形式返回,示例代码如下:

var s = "abc,abcd,aaa";
ss = s.split(",");// 在每个逗号(,)处进行分解。

14、纯函数和不纯函数

  • Array.slice(start,end)原数组不改变,从start开始到end结束,顾前不顾后。(纯函数)
  • Array.splice(index,howmany,arr1,arr2...) ,删除元素并添加元素,从index位置开始删除howmany个元素,并将arr1、arr2...数据从index位置依次插入。howmany为0时,则不删除元素。原数组改变。(不纯函数)

15、lodash

是一个纯函数的功能库,提供了对数组、数字、对象、字符串、函数等操作的一些方法

16、柯里化 (Currying):

当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变) 然后返回一个新的函数接收剩余的参数,返回结果

17、lodash 中的柯里化函数

_.curry(func) 功能:创建一个函数,该函数接收一个或多个 func 的参数,如果 func 所需要的参数都被提 供则执行 func 并返回执行的结果。否则继续返回该函数并等待接收剩余的参数。 参数:需要柯里化的函数

18、…args剩余参数(展开运算符)

允许一个表达式在某处展开。展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)的地方可以使用。剩余参数语法允许我们将一个不定数量的参数表示为一个数组。

19、总结

柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数 这是一种对函数参数的'缓存' 让函数变的更灵活,让函数的粒度更小 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能