call方法
call方法改变函数中this的指向,同时调用函数。
const res1 = fn.call(obj, 2,3)
===> obj.fn(2, 3) 通过调用call方法,方法内部将fn函数挂载到了obj的属性(tempFn)上,并通过obj.tempFn调用外部的fn方法,并将结果返回
Function.prototype.call = function(obj, ...args) {
// 因为this应该指向函数的调用者,又因为fn.call()。fn调用了call方法,所以call中的this就指向fn函数
if (obj === undefined || obj === null)
obj = obj || window // 如果obj为undefined或null调用call使函数中的this指向window
// 给obj中添加一个方法:tempFn: this
obj.tempFn = this
const result = obj.tempFn(...args) // 调用fn函数并传参
delete obj.tempFn // 删除obj上的tempFn
return result // 将调用函数的返回值返回
}
apply方法
apply方法改变this执行并同时调用函数。第一个参数是函数要指向的对象, 第二个参数是一个数组。 实现方法和call类似。
Function.prototype.apply = function(obj, args) {
if (obj === undefined || obj === null) {
obj = obj || window
}
obj.tempFn = this
const result = obj.tempFn(...args)
delete obj.tempFn
return result
}
bind方法
bind方法改变函数内部的this指向,同时返回一个新的函数,不改变原来的函数。
const res3 = fn.bind(obj, 2,3)(4,5)
=>const resFn = fn.bind(obj, 2, 3)
const res3 = resFn(4, 5)
Function.prototype.bind = function(obj, ...args) {
return (...args2) => {
return this.call(obj, ...args, ...args2)
}
}
方法测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function fn(a, b) {
console.log(a, b, this)
return a + b
}
const res1 = fn.call(obj, 2,3)
console.log(res1)
const res2 = fn.apply(obj, [2,9])
console.log(res2)
const res3 = fn.bind(obj, 2,3)(4,5)
console.log(res3)
</script>
</body>
</html>