什么是call,使用js模拟一个call的原理
程序员文章站
2022-03-21 13:04:06
什么是call,使用js模拟一个call的原理让.call前面的函数立即执行 函数的this指向call的第一个参数// ==========call的基本使用function fn(){ console.log(this) } fn();//windowfn.call()//call没有传参,fn也会执行,fn中的this指向window fn.call(123)//传基本数据类型,call内部会包装成对象 {123} let obj={name:'hanhan'}; fn.ca...
什么是call,使用js模拟一个call的原理
让.call前面的函数立即执行 函数的this指向call的第一个参数
// ==========call的基本使用
function fn(){
console.log(this)
}
fn();//window
fn.call()//call没有传参,fn也会执行,fn中的this指向window
fn.call(123)//传基本数据类型,call内部会包装成对象 {123}
let obj={name:'hanhan'};
fn.call(obj)//fn中的this就指向obj
// call传参
function fn(a,b){
console.log(this)
return a+b
}
let obj={name:'hanhan'}
let res=fn.call(obj,1,2)
console.log(res)
// ===============使用js模拟call原理
// 第一步,先写个立即执行函数
;(function(){
function mycall(context){
// 第三步,模拟传参,如果第一个参数是基本数据类型,需要强制类型转成引用数据类型Object
// 还需要判断是否传参了,这里使用三元运算符表达式。如果有就包装成对象,本身就是对象,包装后也没有影响;如果没有就是window
context=context?Object(context):window
// 第四步,this指向fn context.fn=this 参数的fn属性挂上this
context.fn=this;
// 第五步,参数会很多,利用arguments 先定义一个容器去接收 然后for循环遍历arguments
var args=[];
// 注意 i=1,要把第一个参数排除掉
for(var i=1;i<arguments.length;i++){
args.push(arguments[i])
}
//第六步,让fn执行context.fn(),然后进行传参,把数据展开放进去
// 调用context.fn()时会有返回值,返回这个参数 ...args 利用拓展运算符展开
let res=context.fn(...args)
// 第七步,返回之前把前面赋给得fn属性删掉,delete context.fn
delete context.fn;
return res;
}
// 第二步,把mycall挂到函数的原型对象上
Function.prototype.mycall=mycall;
})()
function fn(a,b){
console.log(this)
return a+b
}
let obj={name:'hanhan'}
let res=fn.mycall(obj,1,2)
console.log(res)
本文地址:https://blog.csdn.net/weixin_45935688/article/details/107900563