函数增强
arguments转为Array
查看
JS中函数也是个对象,它也有自己的属性和方法,常见的属性有name和length。
-
name: 函数名。
-
length: 函数未使用参数个数(定义时的形参)。
- 注意:rest参数不参与length的计算。
函数的EC(执行上下文)中关联的VO(variable object
)其在堆内存中对应的AO(activation object
)创建时会初始化arguments引用的类数组对象,但它只是个类数组对象,虽然可以迭代和通过索引访问参数值,但像数组中的filter等方法是不能使用的,所以,我们通常需要将其转化为数组。
方法一:for 循环遍历
1 | function foo(arg1, arg2) { |
方法二:使用数组的slice方法
Array.prototype.slice(start, end)
用于截取数组,内部通过this进行截取,所以我们可以改变this的指向,从而实现arguments向Array的转换。
1 | function foo(arg1, arg2) { |
1 | function foo(arg1, arg2) { |
以上两种方式归根结底都是获取数组原型方法进行处理Array.prototype.slice(start, end)
。
方法三:使用Array.from()
ES6中新增了Array.from()
方法,该方法可以将类数组对象转化为数组。
1 | function foo(arg1, arg2) { |
JS纯函数
查看
在函数式编程中有一个非常重要的概念叫纯函数,JS符合函数式编程的范式,所以JS存在纯函数的概念。
什么纯函数
-
确定的输入,一定产生确定的输出。
- 在函数调用中,加入输入的参数一致,返回的结果不是能改变的。
- 即不能调用并改变外部变量,如在全局作用域下使用闭包的特性。
-
函数在执行过程中,不能产生副作用。
- 不能在调用的同时影响外部变量,以影响后续的使用,导致结果的不一致。
副作用:在计算机科学中,副作用表示在执行一个函数的时候,除了返回函数值外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储。
如下,获取obj的name属性时,操作了obj,导致后续obj的使用出现了变化。
1 | var obj = { name: '大梦想家' } |
副作用往往是产生bug的温床。
纯函数的案例
-
如数组的slice方法就是个纯函数,因为slice方法不会改变原数组,而是返回一个新的数组。
-
而数组的splice方法则会改变原数组,所以splice方法不是纯函数。
纯函数的好处
-
可以安心编写和使用,不必担心对外部的影响。
-
React中就要求我们无论是函数还是class声明一个组件,这个组件都必须像纯函数一样,保护它们的props不被修改。
函数柯里化
查看
什么是函数柯里化
-
只传递一部分参数,返回一个函数,用返回的函数去处理剩余的参数,此过程就称为柯里化(Currying)。
-
柯里化是一种对函数的转化,不会对函数进行调用。
-
柯里化将一个可调用的函数f(a, b, c)转化为可调用的f(a)(b)©。
柯里化优势
-
函数的职责单一
- 在函数式编程中,我们其实往往希望一个函数处理的问题尽可能单一,而不是将一大堆的处理过程交给一个函数来处理。
- 那么我们是否可以将每次传入的参数在单一的函数中处理,处理完后在下一个函数中再使用处理后的结果。
1 | function add(x) { |
-
函数的参数复用
1 | function createAdder(num){ |
自动柯里化函数
将普通函数转换为柯里化函数。
以下代码仅可在最后一次调用时改变this指向有效。
1 | function foo(args1, arg2, arg3) { |
组合函数
查看
组合函数的概念
我们需要对一个数据进行操作,需要执行两个以上的函数,而且这两个函数是依次执行的。如下代码:
1 | function mul(num) { |
实现组合函数
组合函数一般是最初的函数接受较多参数,然后将其返回值交予其他函数进行操作。
1 | function compose(...fns) { |