函数家族的崛起之路 —— call()、apply()、bind()

1,159 阅读3分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战

函数:家族(国家)

this:语言(中文)

内部变量,内部方法:悠久的历史文化遗产

我们可以把函数看作是一个国家的发展史,this 是这个国家的用于交流的语言,内部变量和方法可以看作是这个国家传承下来的悠久的历史文化遗产。

我们国家历史悠久,经历了各朝各代,经历的战火硝烟,先辈们通过一代又一代的努力,给我们留下了丰厚的文化遗产,我们也通过学习这些文化遗产,组建了自己的小家,更让祖国这个大家庭不断地壮大。

同样地,在函数这个大家族的发展中,也存在着相同的情况。

// Pre 作为一个家族的发起人
function Pre(a, b) {
  this.a = a; // a 是 Pre 留给后代的资产
  this.b = b; // b 也是 Pre 留给后代的资产
  this.c = 'c'; // b 也是 Pre 留给后代的资产
}

// Pre1 是 Pre 的第一个孩子
function Pre1(a, b) {
  Pre.call(this, a, b); // Pre1 通过 call 继承了父辈 Pre 的留下来的资产 a,b,c
  this.d = 'd1'; // Pre1 通过自己的不断努力在父辈的基础上,又为后代赚来了 d 这个资产
}

// Pre2 是 Pre 的第二个孩子
function Pre2(a, b) {
  Pre.apply(this, [a, b]); // Pre2 通过 apply 继承了父辈 Pre 的留下来的资产 a,b,c
  this.d = 'd2'; // Pre2 通过自己的不断努力在父辈的基础上,又为后代赚来了 d 这个资产(这里 Pre2 赚来的资产 d 与 Pre1 赚来的资产 d 可不是一样的哟)
  this.count = 99
}

// Pre21 是 Pre2 的第一个孩子
function Pre21(a, b) {
  Pre2.bind(this); // Pre21 通过 bind 继承了父辈 Pre2 的留下来的资产 a,b,c,d, count
  this.countS = this.count * 2; // Pre21 继承到了 Pre2 留下来的 count,并通过自己的努力 💪,让父辈留下来的count 资产获得了成倍的收益
}

// Pre 的其他孩子 以及 Pre1、 Pre2、 Pre21 等的后代也都可以通过 call、apply、bind 去继承父辈留下来的资产

函数家族(以 Pre 为发起人)的崛起就是这么简单,每代函数不断地继承(call、apply、bind)父代的留下来的资产(Pre 的内部变量、内部方法。。。),并在其基础上,不断地努力去发展获取自己的资产(调用 call 的词法作用域中的其他变量和方法),再留给后代作为发展的资本。

小结:

fn.call(this, a, b)

fn.apply(this, [a, b])

fn.bind(this, [, arg1[, arg2[, ...]]])

call、apply、bind 三者的第一个参数都是绑定 this 的指向为当前作用域

call 的第二个参数是参数列表

apply 的第二个参数是参数数组

bind 的第二个参数可以是参数列表,也可以是一个柯里化形式的参数

注:

bind 返回的的一定一个函数

若把 bind 返回的函数作为一个构造函数,通过new 去引用的话,this 的指向就会指向当前的构造函数的实例,而不是 bind 绑定的作用域中的 this