欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

什么是call,使用js模拟一个call的原理

程序员文章站 2022-06-22 11:34:17
什么是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

相关标签: js