【深入理解JS核心技术】15. 什么是柯里化函数
柯里化是将具有多个参数的函数转换为一系列函数的过程,每个函数只有一个参数。Currying 以数学家Haskell Curry的名字命名。通过应用柯里化,n 元函数将其转换为一元函数。
让我们举一个 n 元函数的例子,以及它是如何变成柯里化函数的,
const multiArgFunction = (a, b, c) => a + b + c;
console.log(multiArgFunction(1, 2, 3)); // 6
const curryUnaryFunction = (a) => (b) => (c) => a + b + c;
curryUnaryFunction(1); // returns a function: b => c => 1 + b + c
curryUnaryFunction(1)(2); // returns a function: c => 3 + c
curryUnaryFunction(1)(2)(3); // returns the number 6
复制代码
Curried 函数对于提高代码的可重用性和函数组合非常有用。
函数声明与函数表达式
JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
// 没问题
console.log(sum(10, 10));
function sum(num1, num2) {
return num1 + num2;
}
复制代码
代码可以正常运行,因为函数声明会在任何代码执行之前先被读取并添加到执行上下文。这个过程叫作函数声明提升。
在执行代码时,JavaScript引擎会先执行一遍扫描,把发现的函数声明提升到源代码树的顶部。因此即使函数定义出现在调用它们的代码之后,引擎也会把函数声明提升到顶部。
改为函数表达式就回出错:
// 会出错
console.log(sum(10, 10));
let sum = function(num1, num2) {
return num1 + num2;
};
复制代码
函数作为值
因为函数名在ECMAScript中就是变量,所以函数可以用在任何可以使用变量的地方。这意味着不仅可以把函数作为参数传给另一个函数,而且还可以在一个函数中返回另一个函数。
函数表达式
定义函数有两种方式:函数声明和函数表达式。
函数声明:
function functionName(arg0, arg1, arg2) {
// 函数体
}
复制代码
函数声明的关键特点是函数声明提升,即函数声明会在代码执行之前获得定义。这意味着函数声明可以出现在调用它的代码之后:
sayHi();
function sayHi() {
console.log('Hi!');
}
复制代码
因为 JavaScript 引擎会先读取函数声明,然后再执行代码。
第二种创建函数的方式就是函数表达式。
let functionName = function(arg0, arg1, arg2) {
// 函数体
}
复制代码
函数表达式看起来就像一个普通的变量定义和赋值,即创建一个函数再把它赋值给一个变量functionName。
这样创建的函数叫作匿名函数(anonymous funtion),因为 function 关键字后面没有标识符。(匿名函数有也时候也被称为兰姆达函数)。
任何时候,只要函数被当作值来使用,它就是一个函数表达式。
未完结!更多内容尽情期待下一节~
【深入理解JS核心技术】欢迎各位观众老爷,求点赞,求关注,求转发~
深入理解JS核心技术
Number | Title |
---|---|
1 | 在 JavaScript 中创建对象的可能方式有哪些 |
2 | 什么是原型链 |
3 | 调用、应用和绑定有什么区别 |
4 | 什么是 JSON 及其常用操作 |
5 | 数组切片方法的目的是什么 |
6 | 数组拼接方法的目的是什么 |
7 | 切片和拼接有什么区别 |
8 | 你如何比较Object和Map |
9 | == 和 === 运算符有什么区别 |
10 | 什么是 lambda 或箭头函数 |
11 | 什么是一级函数 |
12 | 什么是一阶函数 |
13 | 什么是高阶函数 |
14 | 什么是一元函数 |
15 | 什么是柯里化函数 |
16 | 什么是纯函数 |
17 | let 关键字的作用是什么 |
18 | let 和 var 有什么区别 |
19 | 选择名称let作为关键字的原因是什么 |
20 | 如何在 switch 块中重新声明变量而不会出错 |
21 | 什么是暂时性死区 |
22 | 什么是 IIFE(立即调用函数表达式) |