1.函数柯里化:传递给函数一部分参数来调用它,让他返回一个函数去处理剩下的函数。
//柯里化之前
function add(x, y) {
return x + y
}
add(1, 2)//3
//柯里化之后
function addX(y) {
return function (x) {
return x + y
}
}
addX(2)(1)//3
//利用bind
function foo(p1, p2) {
this.val = p1 + p2;
}
var bar = foo.bind(null, 'p1');
var baz = new bar('p2');
console.log(baz.val)
柯里化是一种“预加载”函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上,这是一种对参数的“缓存”,是一种非常高效的函数编写方法。
2.惰性函数:通过重写函数的方式,在第二次调用该函数时直接返回结果。
var xhr = null
function ajax() {
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax = () => xhr;
return xhr
}
这样在第二次调用该函数的时候就不会走if语句了
3.递归(调用函数自身)
// 1.普通递归,深度过大,会造成堆栈溢出
// sum(5+sum(4))
// sum(5+4+sum(3))
// sum(5+4+3+sum(2))
// sum(5+4+3+2+sum(1))
// sum(5+4+3+2+1)
// sum(5+4+3+3)
// sum(5+10)
// 15
function sum1(x) {
if (x === 1) return 1;
return x + sum(x - 1);
}
// 2.尾递归
// sum(5,0)
// sum(4,5)
// sum(3,9)
// sum(2,12)
// sum(1,14)
// sum(15)
function sum2(x, temp) {
if (x === 1) return x + temp;
return sum2(x - 1, x + temp);
}
4.纯函数
如果给出相同的参数,它返回相同的结果。 想象一下,我们想要实现一个计算圆的面积的函数。
不是纯函数会这样做,接收radius
作为参数,然后计算radius * radius * PI
:
let PI = 3.14;
const calculateArea = (radius) => radius * radius * PI;
calculateArea(10); // returns 314.0
为什么这是一个不纯函数?原因很简单,因为它使用了一个没有作为参数传递给函数的全局对象。
现在,想象一些数学家认为圆周率的值实际上是42
并且修改了全局对象的值。
不纯函数得到10 * 10 * 42 = 4200
。对于相同的参数(radius = 10
),我们得到了不同的结果。
修复它:
let PI = 3.14;
const calculateArea = (radius, pi) => radius * radius * pi;
calculateArea(10, PI); // returns 314.0
现在把 PI
的值作为参数传递给函数,这样就没有外部对象引入。
radius = 10
和PI = 3.14
,始终都会得到相同的结果:314.0
。radius = 10
和 PI = 42
,总是得到相同的结果:4200
函数是 JS 中的一级公民5.函数是 JS 中的一级公民
其思想是将函数视为值,并将函数作为数据传递。通过这种方式,我们可以组合不同的函数来创建具有新行为的新函数。
const sum = (a, b) => a + b;
const subtraction = (a, b) => a - b;
const doubleOperator = (f, a, b) => f(a, b) * 2;
doubleOperator(sum, 3, 1); // 8
doubleOperator(subtraction, 3, 1); // 4
6.高阶函数
当我们讨论高阶函数时,通常包括以下几点: