目录
- 这三个函数的 特点
call & apply & bind
第一个参数,到底传的什么- 这三个函数实际解决的是什么问题?
先看看怎么调用
let obj = {
arr: [1, 6, 3, 5],
getArr: function() {
console.log(
this.arr
)
}
}
// 1.call
Math.max.call(this, ...obj.arr) // output 6
// 2.apply
Math.max.apply(this, obj.arr) // output 6
// 3.bind
let getArr = obj.getArr;
getArr() // undefined
getArr = getArr.bind(obj)
getArr() // [1, 6, 3, 5]
特点
- call
第一个参数是当前上下文,而call 函数的实参 是只能一个一个传入的。 - apply
第一个参数为当前上下文,而apply函数 是可以直接传入数组的 - bind
将上下文绑定到传入的参数。
实现
call
Function.prototype.mycall = function(context ) {
if (typeof this != 'function') {
throw new TypeError('this is not a function')
}
// 位置1
context = context || window
// 位置2
context.fn = this
let arg = [...arguments].slice(1);
let res = context.fn(...arg)
delete context.fn
return res
}
call apply bind
第一个传入的都是当前上下文- 位置1:将上下文传入, 如果传入
null
则指向window
- 位置2:当我们调用
mycall
函数时,this
指向.(点)
前的函数,然后赋值给context
- 然后通过
arguments
拿去传入参数 - 调用 记得用完删掉就行。
apply
实现思路和 call
函数一样,只是参数 一个是单个,一个是数组。
Function.prototype.myapply = function(context) {
if (typeof this != 'function') {
throw new TypeError('this is not a function')
}
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
最重要的一点 就是 将上下文 指向传入的参数中
Function.prototype.mybind = function(context) {
if (typeof this != 'function') {
throw new TypeError('this is not a func')
}
let _this = this
let arg = [...arguments].slice(1)
return function F() {
return _this.apply(context, arg.concat(...arguments))
}
}
var person = {
name: 'Gavin',
getName() {
console.log(this.name)
return this.name
}
}
person.getName() // Gavin
var getName = person.getName
getName() // undefined
var Gavin = getName.mybind(person)
console.log(Gavin()) // Gavin
_this
指向.
前的getName
函数- 然后 用
apply
函数 将getName函数
的上下文指向person(即 context)
实际解决的问题
就是当 当前上下文
即 this
指向不是我们想要的时, 就可以使用这三个函数 将 this
指向我们想要的结果