今天来手写一下call,apply和bind
对于手写这件事,不仅仅是为了应对面试,更是锻炼一个人的思维能力,检验自己对知识的掌握程度,所以不能一味的去背诵,而是要明白其中的道理!!!!
咱们老规矩 ,对于call,apply和bind不了解的同学可以上MDN经行查阅,下面就直接开始简单实现
实现前的导读:通过以上三种方式绑定this的时候,形式都是fn.call(thisObject, 参数),那么我们要如何做到让thisObject调用fn呢;说到这里,想必已经有想到处理方法了吧;是的,咱们就可以给thisObject添加一个属性,给这个属性赋值为需要执行的函数,通过thisObject.fn(参数)执行即可。
call的实现
Function.prototype.call = function (thisObject, ...arg) {
//针对浏览器实现
thisObject = thisObject == null ? window : thisObject
//保存需要执行的函数
const fn = Symbol()
thisObject[fn] = this
// 调用
const res = thisObject[fn](...arg)
//及时销毁,防止污染对象
delete thisObject[fn]
return res
}
apply的实现
上面我们刚刚把call进行了简单的实现,那么apply也就是差不多的思路了,他们只是传递参数的方式不一样
Function.prototype.tapply = function (thisObject, arg) {
thisObject = thisObject == null ? window : thisObject
arg = arg ? arg : []
const fn = Symbol()
thisObject[fn] = this
//apply要求传递的参数是数组,所以咱们调用的时候就需要对其进行展开
const res = thisObject[fn](...arg)
delete thisObject[fn]
return res
}
bind的实现
bind需要考虑的情况稍微多一点,具体看下面的实现
Function.prototype.bind = function (thisObject, ...arg1) {
//基本处理就不经行过多的解释啦
thisObject = thisObject == null ? window : thisObject
const fn = Symbol()
thisObject[fn] = this
//返回一个函数
return function (...arg2) {
//返回后的函数能够再次经行参数的传递
arg = arg1.concat(arg2)//拼接两次的参数
//调用函数
const res = thisObject[fn](...arg)
delete thisObject[fn]
//返回结果
return res
}
}
好了,到了这里本篇文章就结束了;咱们把call,apply和bind都简单的实现了一下,我想通过这次的实现,对这三个绑定this的函数有更清晰的认识了吧