思路
改变函数内部的this指向,可以理解为在对象上把这个函数挂上去,再执行对象上的这个函数
Call函数实现
改变this指向并执行函数
//Call函数 参数用结构的方法
Function.prototype.myCall = function(context,...args){
// this改变指向的目标对象
let newObj = context || global
// 目标对象挂载fn函数 === 调用myApply的函数(this指向调用myApply的函数)
newObj.fn = this
// 执行这个函数,保存结果
let result = newObj.fn(...args)
// 返回指执行结果
// 释放
delete newObj.fn
return result
}
Apply函数实现
改变this执行,并执行函数,只是传参为数组形式
//Apply函数 参数用类数组
Function.prototype.myApply = function(context){
// this改变指向的目标对象
let newObj = context || global
// 目标对象挂载fn函数 === 调用myApply的函数(this指向调用myApply的函数)
newObj.fn = this
// 判断是否有其它参数,执行这个函数,保存结果
let result
if(arguments[1]){
//结构成数组调用数组方法 省去第一个对象
result = newObj.fn(...arguments[1])
}else{
result = newObj.fn()
}
//释放
delete newObj.fn
// 返回指执行结果
return result
}
bind函数实现
改变this指向,不执行,返回这个函数
//Bind函数 传值类似call 需要考虑函数柯里化
Function.prototype.myBind = function(context,...frontargs){
// // 判断是不是函数调用的myBind方法
// if(typeof this !== 'function'){
// throw new TypeError('Error')
// }
// 保留这个函数
let _this = this
// 返回一个函数,外部执行这个函数才会有结果,此处考虑柯里化
return function fn(...backargs){
/*
这种情况
let a = new fn()
a.bind(xxx)
*/
if(this instanceof fn){
return new _this(...frontargs,...backargs)
}
return _this.myCall(context,...frontargs,...backargs)
}
}
测试
let obj = {
0:1,
name: "dzw",
}
global.name = '小大小'
function fn(age1,age2){
let name = this.name
console.log(name,age1,age2)
}
fn.myBind(obj,11)(14)