用法

call、apply、bind都是用来改变函数的this的指向;
call、apply、bind三者第一个参数都是this要指向的对象,也就是想指定的上下文;
call、apply、bind三者都可以利用后续参数传参;
bind是返回对应函数,便于稍后调用;apply、call则是立即调用 ;
call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里;

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = {name:'zhangsan'}
var b = {name:'lisi'}
var obj = {
name:'wangwu',
sayName:function(){
console.log(this.name)
}
}

obj.sayName() //wangwu
obj.sayName.call(a) //zhangsan
obj.sayName.apply(b) //lisi
obj.sayName.bind(b)() //lisi

手写call、apply、bind

实现原理都是通过对象属性的方法绑定该函数,通过对象调用方法来改this,bind返回一个函数即可;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Function.prototype.myCall = function(context,...args) {
context.fn = this //函数保存为context.fn
const result = context.fn(args)
delete context.fn
return result
}
Function.prototype.myApply = function(context,args) {
context.fn = this //函数保存为context.fn
const result =(args && args.length)? context.fn(args) : context.fn()
delete context.fn
return result
}
Function.prototype.myBind = function(context,...args) {
context.fn = this //函数保存为context.fn
return function (){
const newArgs = args.concat(...arguments)
const result = context.fn(args)
delete context.fn
return result
}
}