call
- 简易版(不支持传参的方法)实现思路:
- 给目标对象创建一个属性,将要调用的方法绑定到这个属性上
- 直接运行刚刚创建的属性
- 删除这个属性
这样就间接绑定了this的指向,并实现了call
Function.prototype.mycall=function(con){
con.fun = this;
con.fun();
delete con.fun;
}
let obj1 = {
name:"helloworld"
}
function fn(){
console.log(this.name);
}
fn.call(obj1);
fn.mycall(obj1);
- 中等版,支持传参函数的call实现思路
- 主要思路如上,不一样的是要通过arguments取出除第一位之外的所有参数放到一个数组里,然后通过展开运算符给要执行的函数或方法传参,如下:
Function.prototype.mycall = function(con){
con.fun = this; //给目标对象新建一个属性,绑定这个函数
let paramsArr = new Array(); //新建一个空数组
for(let i=1;i<arguments.length;i++){
paramsArr.push(arguments[i]);
}
con.fun(...paramsArr); //运行一下
delete con.fun; //删除目标对象上的fun属性
}
let testObj = { //定义一个对象
num1:10,
num2:9.5
}
function add(p1,p2,p3){ //定义函数
console.log(this.num1+this.num2+p1+p2+p3);
}
add.call(testObj,1,2,3); //原生call 25.5
add.mycall(testObj,1,2,3);//实现的call 25.5
Function.prototype.mycall = function(con){
con = new Object(con) || window || global;
con.fun = this;
let paramsArr = new Array();
for(let i=1;i<arguments.length;i++){
paramsArr.push(arguments[i]);
}
con.fun(...paramsArr);
delete con.fun;
}
function conso(p1,p2,p3){
console.log(this.num1,this.num2,p1,p2,p3);
}
conso.call(1,2,3);
conso.mycall(1,2,3);