bind、call、apply方法常用于改调用函数并指定函数执行时的上下文(即this关键字的值)以及参数列表。例如将一个类数组对象转换为真正的数组,以便使用数组的方法、Object原型上的toString方法判断数据类型等功能。
call
call 方法调用执行函数并用第一个参数改变函数执行时的上下文,可以传多个参数列表
实现
1 2 3 4 5 6 7 8 9 10 11
| Function.prototype.myCall = function(context, ...args) { context = context || window const symbol = Symbol(); context[symbol] = this const result = context[symbol](...args); delete context[symbol]; return result; }
|
测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13
| var x = 1000 function b(...arg) { console.log(this.x ,arg) } let a = { x: 1 }
b.call(a, 2, 3, 4)
b.myCall(null, 2, 3, 4)
|
demo
apply
call 方法调用执行函数并用第一个参数改变函数执行时的上下文,第二个参数是一个数组(或一个类数组对象)的形式提供的参数。 和call 的区别在于第二个参数 call 是参数列表
实现
1 2 3 4 5 6 7 8 9 10 11
| Function.prototype.myApply = function(context, args) { context = context || window const symbol = Symbol(); context[symbol] = this const result = context[symbol](...args); delete context[symbol]; return result; }
|
测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13
| var x = 1000 function b(...arg) { console.log(this.x ,arg) } let a = { x: 1 }
b.apply(a, [2, 3, 4])
b.myApply(null, [2, 3, 4])
|
demo
bind
bind方法和call、apply都不一样,先绑定context 上下文和参数,创建一个新的函数返回。参数将作为新函数的参数,供调用时使用。
实现
1 2 3 4 5 6 7
| Function.prototype.myBind = function(context, ...args1) { const fn = this; return function(...args2) { context = context || this; return fn.apply(context, [...args1, ...args2]); } }
|
测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Function.prototype.myBind = function(context, ...args1) { const fn = this; return function(...args2) { context = context || this; return fn.apply(context, [...args1, ...args2]); } }
var x = 1000 function b(...arg) { console.log(this.x ,arg) } let a = { x: 1 }
let bind1 = b.bind(a, 2, [3, 4]) bind1()
let bind2 = b.myBind(null, 2, [3, 4]) bind2()
|