call
- 在方法调用中,this 总是指向调用它所在方法的对象,this 的指向与所在方法的调用位置有关,而与方法的声明位置无关(箭头函数this永远指向它所在的作用域
- 下面是一个小栗子🌰
const myObj = {
number: 123
}
const fn = function () {
console.log(this.number)
}
fn()
const myObj = {
number: 123,
fn: function () {
console.log(this.number)
}
}
myObj.fn()
Function.prototype.mycall = function (thisArg) {
if (typeof this !== 'function') {
throw TypeError('Error')
}
const fn = Symbol('fn')
const arg = [...arguments].splice(1)
thisArg = thisArg || window
thisArg[fn] = this
const result = thisArg[fn](...arg)
delete thisArg[fn]
return result
}
apply
Function.prototype.myapply = function (thisArg) {
if (typeof this !== 'function') {
throw TypeError('Error')
}
const fn = Symbol('fn')
const arg = const arg = arguments[1]
thisArg = thisArg || window
thisArg[fn] = this
const result = thisArg[fn](...arg)
delete thisArg[fn]
return result
}
bind
- call、apply、bind 本质都是改变 this 的指向,不同点 call、apply 是直接调用函数,bind 是返回一个新的函数
Function.prototype.myBind = function (thisArg) {
if (typeof this !== 'function') {
throw TypeError('Error')
}
const self = this
const arg = Array.prototype.splice.call(arguments, 1)
const epFn = function () {}
if (this.prototype) {
epFn.prototype = this.prototype
}
const bound = function () {
return self.apply(
this instanceof epFn ? this : thisArg,
arg.concat(Array.prototype.splice.call(arguments))
)
}
bound.prototype = new epFn()
return bound
}