美文网首页
Javascript中call,apply的实现原理

Javascript中call,apply的实现原理

作者: 再见噜噜班 | 来源:发表于2019-11-25 21:02 被阅读0次

    call,apply应用场景

    首先,来看下面这一个例子:

    let person = {
        name:'king',
        greet:function(){
                console.log(`hello,${this.name}`)
        }
    }
    person.greet();   //hello,king
    
    

    现在,有另一个对象person2,let person2={name:'sara'}。如果他也想调用greet方法,那么可以这么实现:为person2添加方法,指向person的greet方法,即person2.greet=person.greet。然而,person2仅仅是临时需要调用greet方法,这样重新为person2定义greet方法显得不是很有必要,这时候就需要call或者apply出场了。
    利用call,apply可以这么实现:

    person.greet.call(person2)  //hello,sara
    person.greet.apply(person2)  //hello,sara
    
    

    其实call和apply的用处是一样的,就是让对象临时调用本不属于自己的方法,而不用为自身添加该方法。两者的不同在于调用的时候传参的形式,call以单个参数依次传入,apply以数组的方式传入,以上greet方法没有形参,所以不能体现出不同。以上例子稍作修改即可体现:

    let person = {
            name:'king',
            greet:function(str){
                    console.log(`${str},${this.name}`)
            }
    }
    let person2 = {name:'sara'}
    person.greet.call(person2,'hi')  //hi,sara
    person.greet.apply(person2,['hi']) //hi,sara
    

    模拟实现原理

    Function.prototype.call2=function(context){
            let ctx = context || window
            ctx.fn = this //此处this指向调用call2函数的函数对象,例子中是peoson.greet
            //传参,call2函数的第一个参数是需要调用函数的对象,函数参数从第二个开始
            let args=[]
            for(let i=1,len=arguments.length;i<len;i++){
                    args.push(arguments[i])
            }
            ctx.fn(...args) //es6扩展运算符,相当于ctx.fn(args[0],args[1],...args[args.length-1])
            delete ctx.fn //用完删除,释放空间
    }
    person.greet.call2(person2,'hi')   //hi,sara
    
    Function.prototype.apply2=function(context,arr){
            let ctx = context || window
            ctx.fn = this 
            //判断是否带参数,以及参数是否为数组
            if(!arr){
                    ctx.fn()
            }else{
                    if(!arr instanceof Array){
                            throw new Error('params must be array')
                    }else{
                            ctx.fn(...arr)
                    }
            }
            delete ctx.fn 
            
    }
    person.greet.apply2(person2,['hi']) //hi,sara
    

    简单的说,call,apply可以让一个函数临时成为对象的方法,即让函数中的this可以指向该对象。
    以上是我对call,apply的理解,若有不对之处,还望各位看官批评指正。

    相关文章

      网友评论

          本文标题:Javascript中call,apply的实现原理

          本文链接:https://www.haomeiwen.com/subject/ugajwctx.html