目錄
- 這三個函數的 特點
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
指向我們想要的結果