<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
Function.prototype.myCall = function (thisArg = window, ...args) {
// 使用Symbol避免属性名冲突
const fn = Symbol('fn')
// 处理thisArg为null或undefined的情况
thisArg = thisArg || window
// 将函数作为对象的方法
// 这里的this是下面的test
thisArg[fn] = this
// 执行函数并获取结果
const result = thisArg[fn](...args)
// 删除临时属性
delete thisArg[fn]
// 返回函数执行结果
return result
}
const test = (a, b, c) => {
console.log(a, b, c)
}
test.myCall({ a: 1 }, 2, 3, 4)
//myApply是myCall的另一种实现,只是参数不一样 接收数组
Function.prototype.myApply = function (thisArg = window, args) {
// 使用Symbol创建唯一的属性名,避免命名冲突
const fn = Symbol('fn')
// 如果thisArg为null或undefined,则将其设置为window对象
thisArg = thisArg || window
// 将当前函数(this)作为thisArg对象的一个方法
thisArg[fn] = this
// 使用展开运算符将参数数组展开并执行函数,获取返回结果
const result = thisArg[fn](...args)
// 删除临时添加的方法
delete thisArg[fn]
// 返回函数执行的结果
return result
}
const test2 = (a, b, c) => {
console.log(a, b, c)
}
test2.myApply({ a: 1 }, [2, 3, 4])
//mybind 返回一个函数 bind需要自己调用
Function.prototype.myBind = function (thisArg = window, ...args1) {
// 为Function原型添加myBind方法,接收两个参数:
// thisArg: 要绑定的this值,默认为window
// args1: 第一次调用时传入的参数列表
return (...args2) => {
// 返回一个箭头函数,该函数接收第二次调用时传入的参数args2
// 使用箭头函数可以保持this的指向不变
// 将两次传入的参数合并成最终的参数列表
// args1是第一次bind时传入的参数
// args2是返回的函数执行时传入的参数
const finalArgs = [...args1, ...args2]
// 使用之前定义的myCall方法来执行函数
// this指向原始函数
// thisArg作为函数执行时的this值
// 展开finalArgs作为函数的参数
return this.myCall(thisArg, ...finalArgs)
}
}
const test3 = (a, b, c) => {
console.log(a, b, c)
}
const bindTest = test3.myBind({ a: 1 }, 2, 3, 4)
bindTest()
</script>
</body>
</html>
手写call,apply,bind函数
最新推荐文章于 2026-06-21 09:58:57 发布

2025

被折叠的 条评论
为什么被折叠?



