JavaScript函数

匿名函数

匿名函数:函数声明时不指定函数名。

匿名函数的用途:多用于封装私有变量,防止变量污染。

匿名函数自运行

1
2
3
(function(){

})()

包裹匿名函数的小括号把匿名函数变成了一个优先执行的表达式,表达式一定会返回结果,且结果为函数本身,再在后面加一个小括号,就等于调用函数。

所有可以把“函数声明”变为表达式的运算符都可以让匿名函数自运行,如:

1
2
3
4
// 使用 + 执行效率最高
+function(){

}()

递归函数

递归函数必须有结束条件,中止递归,向上返回。

回调函数

回调函数指的是函数的使用方式。

把一个函数交给别人,在合适的时候再调用。

这里面还涉及了 this 的指向问题。

构造函数

是对函数的特殊调用方式。

对一个函数使用 new 关键字,返回值是一个对象。

习惯:构造函数首字母大写。

默认参数

语法与 Python 类似。

1
2
3
function fun(形参=默认值, ...) {

}

闭包函数

闭包函数:声明在一个函数中的函数。

闭包的两要素:

  • 函数嵌套

  • 内层函数引用外层函数中定义的变量

闭包的用途:隔离

  • 实现数据私有

  • 模块化

函数的柯里化

把一个多参函数转化为一个单一参数的嵌套函数,这个函数需要多次调用才能获得最终值。

柯里化(currying)又称为“部分求值”。

使用闭包实现。

1
2
3
4
5
6
7
8
9
10
function fun(a, b, c){};

function funCurrying(a) {
return function(b){
return function(c){
return fun(a, b, c);
}
}
}
fun(1, 2, 3) == funCurring(1)(2)(3);

通用柯里化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function curry(fn) {
return function curried(...args) {
if(args.length >= fn.length){
// 最终调用原函数
return fn.apply(this, args);
} else {
return function(..args1) {
// 递归
// 参数合并
return curried.apply(this, args.concat(args1));
}
}
}
}

function sum(a, b, c) {}
const sumCurried = curry(sum);

优点:

  • 让函数更加灵活,参数可以自由组合。

  • 可以生成部分参数预设的函数,便于复用。

缺点:让函数的调用更加复杂,多次传参,降低了可读性。

函数的反柯里化

反柯里化:将柯里化函数转化为接收多个参数的过程。

柯里化函数的第一个参数是原函数。

1
2
3
4
5
6
7
8
9
10
11
Function.prototype.uncurry = function() {
// 指向柯里化函数
let self = this;
// 返回一个普通函数,第一个参数是函数的this,后面是全部传参
return function() {
// 等于 self.call(arguments)
// 等于 arguments[0].self(arguments[1,n-1]);
// 调用柯里化函数,传入所有参数
return Function.prototype.call.apply(self, arguments);
}
}

箭头函数(Arrow Function)

语法:

1
2
3
(形参) => {
函数体
}

箭头函数的特殊点:

  • 箭头函数没有 prototype

  • 箭头函数没有没有自己的 this:this 指向定义该箭头函数所处的的作用域。

箭头函数类似于 inline 函数,单纯的执行代码块。

函数中 this 的指向

普通函数:函数被调用时。

箭头函数:函数所在代码被调用时

  • 对象字面量:对象所处的作用域。
  • 函数:外围函数调用时
  • 构造函数:创建对象时

箭头函数不能通过 call()apply() 改变 this。

不能对一个箭头函数使用 new

Function构造函数和原型

length 属性:函数属性,记录函数形参的个数。

arguments 属性:函数运行环境参数,存储函数的实参。箭头函数没有自己的 this,通过该属性得不到实参。

原型方法

Function.prototype.apply()

应用(立即执行)函数,指定 this 和实参(数组形式)。

Function.prototype.call()

调用(立即执行)函数,指定 this 和实参(剩余参数)。

Function.prototype.bind()

返回一个绑定了 this 和参数的新函数。不会立即执行。

Function.prototype.toString()

获取函数的源码的字符串。

参考

Javascript 中的柯里化与反柯里化-CSDN博客