相同与不同点
大家应该都知道,call,apply,bind的共同点都可以改变this的指向,而不同点呢,就是返回值不同,call,apply的返回值取决于目标函数是否存在返回值,而bind是返回一个新的函数,并把this指向这个函数。而call,apply的区别就是参数的区别,apply是接受一个数组,而call只能接受单个单个的参数(PS:给大家说一个小技巧可以非常容易的记住call和apply的区别,就是apply的首个字母是a,而数组刚好是array,这样大家看到apply就能联想到array啦。)
call的实现
call是es3的方法,我再这里用es6实现了。代码如下:
Function.prototype.Call=function(...args){
var context=args[0]||window;
var argArr=args.slice(1)
context.fn=this;
var result=context.fn(...argArr)
delete context.fn
return result;
}
var obj = {
name: "hty",
sex: "男"
}
function fn(age, pro) {
console.log(`${this.name}是${this.sex}`)//hty是男
console.log(`今年${age}职业是${pro}`)//今年24职业是前端攻城狮
}
fn.Call(obj, "24", "前端攻城狮")
apply的实现
apply同样是es3的方法,其实call和apply逻辑除了参数不同,别的都一样,所以我直接把上面的代码拿下来,改扒改扒。
Function.prototype.Apply=function(...args){
var context=args[0]||window;
var argArr=args.slice(1)
context.fn=this;
var result=context.fn(...argArr[0])
delete context.fn
return result;
}
var obj = {
name: "hty",
sex: "男"
}
function fn(age, pro) {
console.log(`${this.name}是${this.sex}`)//hty是男
console.log(`今年${age}职业是${pro}`)//今年24职业是前端攻城狮
}
fn.Apply(obj,["24", "前端攻城狮"])
bind的实现
bind和call,apply的区别再文章开头已经说过了,就是bind的返回值是一个新的函数,具体逻辑代码如下:
Function.prototype.Bind=function(...args){
var context=args[0]||window;
var args=args.slice(1)
var fbind=this;
fBound=function(...value){
fbind.apply(context,args.concat(value))
}
return fBound
}
var obj = {
name: "hty",
sex: "男"
}
function fn(age, pro,type) {
console.log(`${this.name}是${this.sex}`)//hty是男
console.log(`今年${age}职业是${pro}他在${type}`)//今年24职业是前端攻城狮他在努力
}
fn.bind(obj,"24", "前端攻城狮")("努力")
PS
以上只是简单的实现,还有许多许多许多算法都没有实现,比如new的时候,边界处理等。但是大概原理就是这些,希望能给您带来帮助,谢谢您的阅读。