前言

今天跟朋友讨论了一个面试题,深入探究了一下。

1
2
// 3
// 3

两次输出都是3。期初我们总结为:只执行第一个绑定的,后面执行多少都无效。

???

但是有人就问为啥后面不再输出4 和 5

继续往下看⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️

Function​.prototype​.bind()

以下是 MDN 给出了bind()的定义:
bind()方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。

语法:
function.bind(thisArg[, arg1[, arg2[, …]]])

返回值是:
返回一个原函数的拷贝,并拥有指定的this值和初始参数。

描述:bind() 函数会创建一个新绑定函数(bound function,BF)。绑定函数是一个exotic function object(怪异函数对象,ECMAScript 2015中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数。


分割线


以上好对问题并没有很好的解释,看下面的案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function.prototype.bind = function (scope ,...args ) {
const self = this
return function () {
self.call(scope,args)
}
}

const b = {x:1}
const c = {x:2}

const a = function () {
console.log(this.x)
}

a.bind(b).bind(c)() // output : 1

删除上面Function

1
2
3
4
5
6
7
8
const b = {x:1}
const c = {x:2}

const a = function () {
console.log(this.x)
}

a.bind(b).bind(c)() // output : 1

输出也是1

总结:

也就是说 bind()的实现,相当于使用函数在内部包了一个call/apply,第二次bind()相当于在包住第一次bind(), 故第二次以后的bind 是无法生效的。

再看下面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const b = {x:1}
const c = {x:2}

const a = function () {
console.log(this.x)
}


function test() {
(function(){
a.call(b)
}).call(c)
}

test() //output : 1

差不多可以解释了

感兴趣的可以自己试试。

更加欢迎大家能给出更好的解释或加以指正。