theme: smartblue
highlight: foundation
开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
call apply bind 的实现的面试中几乎必定出现的一些内容,今天来用一篇文章整理一下这里的内容,加深一下JS基础知识体系。同时文章也被收录到我的《JS基础》专栏中,欢迎大家点击收藏加关注。
call的实现
call()
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。
let obj = {name:'plus'}
function getName(a){
console.log(this.name+'_'+a)
}
getName.call(obj,'666') //plus_666
以上的call可以换成用函数的隐式绑定调用的方法来使用 比如
let obj = {
name:'plus',
getName: function(a){
console.log(this.name+'_'+a)
}
}
obj.getName('666') //plus_666
把函数放到要指向的对象中,通过obj.
的隐式调用,就能够改变this的指向
那么根据这个调用方法我们就有思路来实现我们的call方法了
手写call
- 1.在对象中声明一个临时函数,将要执行的函数放到其中
- 2.通过隐式调用
- 3.删除临时函数
- 4.判断传入对象是否为空
_call(fn,...arg) = function(){
if(obj===null||obj===undefined){ //没有指定对象时候
obj = window
}
obj.temp = fn //临时函数
let res = obj.temp(...arg)
delete obj.temp //临时函数完成它的任务就要消失了
return res
}
//改进版
Function.prototype._call = function(obj,...arg){
obj = obj || window //没有指定对象时候 指向window
const temp = Symbol() //小技巧,Symbol可以用来声明一个对象的属性
obj.temp = this //因为call的声明方法是`Function.prototype._call`所以this就是要调用的函数
let res = obj.temp(...arg)
delete obj.temp
return res
}
手写apply
apply的实现基本是和call是差不多的,有区别的一点是对于传入的参数,call接收的是多个参数,apply接收的是一个参数数组
- Function.prototype.apply = function(obj,...arg){
+ Function.prototype.apply = function(obj,arg){
obj = obj || window //没有指定对象时候 指向window
const temp = Symbol() //小技巧,Symbol可以用来声明一个对象的属性
obj.temp = this //因为call的声明方法是`Function.prototype._call`所以this就是要调用的函数
let res = obj.temp(...arg)
delete obj.temp
return res
}
手写bind
bind的实现与call和apply的有点不同,bing中返回的是一个函数,需要对函数进行第二次调用才能真正的执行到函数。我们先来看一下例子。
function getName(a,b,c,d){
console.log(`${a} ${b} ${c} ${d}`)
}
let obj = {}
let b1 = getName.bind(obj,1,2)
b1(3,4)
我们可以看到bind的最终调用是分两次实现的,这个实现类似于是柯里化的实现,那么看了bin的使用后我们就可以来手动写出bind了
步骤分为几步:
- 函数中返回一个函数
- 还是和call、apply函数一样设置一个临时函数
- 在返回的函数中,因为是最后一次执行,将所有参数传入,比如arg1传入的是1、2,arg2传入的是3、4。
Function.prototype._bind = function (obj,...arg1) {
obj = obj || window
const temp = Symbol()
obj[temp] = this
return function(...arg2){
obj[temp](...arg1,...arg2) //obj[temp](1,2,3,4)
}
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容