一、简单实现call函数
call函数原理:给函数的this绑定一个对象并且执行该函数,参数是一个个传的(不是以数组的形式)
Function.prototype.myCall = function(context,...args){
context.$myProps = this
const res = context.$myProps(...args)
delete context.$myProps
return res
}
const obj= {
name:'fish',
age:18
}
function myfun(params){
console.log(this.name,params)
return params
}
const result = myfun.myCall(obj,"是一只小鱼仔")
console.log(result)
二、简单实现apply函数
apply函数原理:给函数的this绑定一个对象并且执行该函数,参数是以数组的形式传入
apply函数与call函数的区别:传参数的形式不同,apply参数是以数组的形式传入。call是逐个传入,以逗号隔开
Function.prototype.myApply = function(context,arr){
context.$myProps = this
const res = context.$myProps(...arr)
delete context.$myProps
return res
}
const obj= {
name:'laosha',
age:18
}
function fn(param1,param2){
console.log(this.name, param1, param2)
return this.age
}
const res = fn.myApply(obj,["小马","小鸡"])
console.log(res)
三、简单实现bind函数
bind函数:只能通过函数调用,返回一个绑定this后的函数
Function.prototype.myBind = function(context){
if(typeof this !== "function"){
throw new Error("不是函数,无法调用myBind")
}
const thatFun = this
return function(...params){
context.$myProps = thatFun
const res = context.$myProps(...params)
delete context.$myProps
return res
}
}
function fn(param1,param2){
console.log(this.name, param1, param2)
}
const obj= {
name:'laosha2',
}
const newFn = fn.myBind(obj)
newFn("小鸟","小尼姑")
四、bind函数优先级最高
说明:一个函数(fn),一旦经过bind绑定之后,那么这个返回的新函数(newFn)通过apply或者call
都无法再更改this的指向
Function.prototype.myBind = function(context){
if(typeof this !== "function"){
throw new Error("不是函数,无法调用myBind")
}
const thatFun = this
return function(...params){
context.$myProps = thatFun
const res = context.$myProps(...params)
delete context.$myProps
return res
}
}
const obj111= {
name:'laosha11111',
}
const obj222= {
name:'laosha22222',
}
function fn(param1,param2){
console.log(this.name, param1, param2)
}
const newFn = fn.myBind(obj111)
newFn.apply(obj222,["小鸟","小尼姑"])
结论:
一个函数fn被bind绑定this后返回的新函数newFn, apply和call无法通过更改newFn的this指向象来影响fn的this指向。
原因解析:
apply和call更改的是newFn函数中this指向,但是newFn在执行的过程中没有用到this,所以就算改变了newFn的 this指向,也不影响fn已经被bind绑定的this对象
Function.prototype.myCall = function(ctx,...args){
ctx.$myProps = this
const res = ctx.$myProps(...args)
delete ctx.$myProps
return res
}
Function.prototype.myBind = function(context){
const thatFun = this
return function(...params){
context.$myProps = thatFun
const res = context.$myProps(...params)
delete context.$myProps
console.log("我是返回的newFn,我的this指向是",this)
return res
}
}
const obj111= { name:'laosha11111'}
const obj222= { name:'laosha22222'}
function fn(){
console.log(this.name)
}
const newFn = fn.myBind(obj111)
newFn.myCall(obj222)