乐趣区

Javascript箭头函数和lambda

() => {} 基本特点

es6 中的箭头函数,在实际开发中确实比较方便,通常来说会有几个特点:

  • 箭头函数中的 this 会绑定在外部作用域
  • 没有 arguments
  • 如果想返回一个对象记得加 () 包裹
  • call 和 apply 不能传入 this
(() => {a: 1})() // 返回值为 undefiend,想返回对象,使用下面的方式
(() => ({a: 1})()

箭头函数和 lambda 表达

lambda 在计算机科学中表示匿名函数,本质上是用来简化操作的。简单来说,是一种表示方法,代表了一定的输入和输出。

step1:

实现一个平方运算表达(x * x):
数学表达式(λ 代表一个表达式的输入):

λx.x * x

用 JavaScript 实现:

(function (x) {return x * x;})()

step2:

在平方的基础上再加 2(x * x + 2):
数学表达式:

(λx.x * x)(λx.x + 2)

用 Javascript 实现:

(function(x) {return x + x})((function () {return x * x})())

其实就是利用了匿名函数然后,再继续嵌套。
但是有了箭头函数,就可以更加简便地实现上面的操作:

(x => x + 2)((x => x * x)())

step3:

更加优雅地实现,其实向上面这种方式,不是特别优雅,可读性不好,需要一种能够更加优雅地方式:

上面的行为抽象出来就是:前一个的输出作为后一个函数的输入,应该怎么实现呢?Javascript 中提供了 reduce 这一个方法。

const action = [
  x => x * x,
  x => x + 2
];

let res = action.reduce((res, cur) => cur(res), 2);

step4:

总结:从上面的过程可以看出来,有两个主要的关键过程:

  • 1、箭头函数是一个匿名函数,简化书写
  • 2、箭头函数作为变量传递给 reduce 函数的回调

所以箭头函数在很大程度上,简化了函数式的操作。其实 lambda 表达式,在 Javascript 中就是匿名函数。

箭头函数使用总结:

  • 箭头函数适合纯函数的操作,比如 map、filter、reduce 等操作
  • 箭头函数内部,一般不要使用 this,因为 this 是和外部作用域绑定的,容易产生问题

问题 1:

function A() {this.foo = 1}

A.prototype.bar = () => console.log(this.foo)

let a = new A()
a.bar()  //undefined

因为对象 a,并没有构成一个作用域。

如果想让 this 指向 A,可以这样写:

function A() {
  this.foo = 1;
  this.bar = () => {console.log('value', this.foo);
  }
}
let a = new A();
a.bar(); //1

因为 bar 的声明在函数 A 的作用域内部。

问题 2:

const A = {
  foo: 1,
  bar: () => {console.log('value', this.foo);
  }
}
let a = Object.create(A);
a.bar(); //undefined

如果想输出正常的值,应该使用 function 定义:

const A = {
  foo: 1,
  bar: function (){console.log('value', this.foo);
  }
}
let a = Object.create(A);
a.bar(); // value 1

参考文档:

lambda 和箭头函数

退出移动版