call、apply、bind封装以及三者区别
相同之处:
改变函数体内 this 的指向。
不同之处:
call、apply的区别:接受参数的方式不一样。
bind:不立即执行。而apply、call 立即执行。
call方法第一个参数是要绑定给 this 的值,后面传入的是一个参数列表。当第一个参数为 null、undefined的时候,默认指向window。
apply接收两个参数,第一个参数是要绑定给 this 的值,第二个参数是一个参数数组。当第一个参数为 null、undefined的时候,默认指向window。
bind和 call 很相似,第一个参数是 this 的指向,从第二个参数开始是接收的参数列表。区别在于 bind 方法返回值是函数以及 bind 接收的参数列表的使用。
call函数
// 思路:将要改变this指向的方法挂到目标this上执行并返回
Function.prototype.mycall = function (context) {
if (typeofthis !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let arg = [...arguments].slice(1)
let result = context.fn(...arg)
delete context.fn
return result
}
apply函数
// 思路:将要改变this指向的方法挂到目标this上执行并返回
Function.prototype.myapply = function (context) {
if (typeofthis !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
bind函数
// 思路:类似call,但返回的是函数
Function.prototype.mybind = function (context) {
if (typeofthis !== 'function') {
throw new TypeError('Error')
}
let _this = this
let arg = [...arguments].slice(1)
return function F() {
// 处理函数使用new的情况
if (this instanceof F) {
return new _this(...arg, ...arguments)
} else {
return _this.apply(context, arg.concat(...arguments))
}
}
}