js基础系列之-------call,apply的实现

我们都知道call与apply能实现this指向的改变,而且该函数执行时立刻返回结果。

 let Person = {
            name: 'Tom',
            say() {
              console.log(this.name)
              
            }
        }
 let person1= {
            name: 'Tom1'
  }

Person.say.call(person1) //Tom1

想让person1执行 Perosn里的say方法。如果person1这个对象本身也有一个say方法,那么我们只需要通过person1.say()执行就可以里,我们也知道person1本身是没有say方法的,那么我们给他加一个不就行了吗? person.say()。这里我们会有一个疑问?不可能每次都加一个固定的say方法吧?这不合理,我哪知道到底是哪个方法?既然我们不能加固定的,那么我们可以这样

person1.fn=xxxx //这个xxx就是say方法。

我们仔细分析Person.say.call(person1)。对于我们的call函数而言。call函数内部this指向的是谁?还是那句话:谁调用它,this就指向谁。Person.say.call()======》是Person.say调用里call()很明显,call内部的this应该指向的是Person.say,所以我们可以初步写出下面的代码:

//Person.say.call(person1)

Person.say.myCall(person1) //Person.say调用mycall,那mycall内部的this就是Person.say

Function.prototye.myCall=function(context,...args){
    
 //context指的就是person1
 //this指向的是Person.say
    
 context.fn=this
 context.fn(...args)
 context.delete(fn)

}

上一步我们说过我们不可能每次都加一个固定的say方法。而我们需要执行这个say方法,而刚好我们知道mycall内部this指向的就是person.say()。那不刚好吗?

我们执行context.fn(..args)同时把参数给传进去,不就相当于给person添加里一个say方法同时执行它。但是我们知道我们给person1添加里一个静态方法,而这个方法其实和person1本身是解耦的,所以我们在办完事以后还的把它删除。

到这里已经基本实现了。但是还有一些问他需要我们思考:

1 如果我们的mycall(context,args)中context不传会怎样?

2 如果我们的mycall(context,args)中传的是一个基本数据类型怎么办?

其实对于问题1很好解决:

如果我们的mycall(context,args)中context不传或者为null,我们默认它为window

而对于问题2

如果我们的mycall(context,args)中传的是一个基本数据类型,我们把基本数据类型转化为其构造函数的对象。比如字符串,它的构造函数就是String,比如number,它的构造函数就是Number。

所以最后的代码我们可以做如下完善

Function.prototype.myCall=function(context,...args){

    let context=context===undefined?window:context;
    
    let type=typeof context;
    
        if(!/^(object|function)$/).test(context){ //是否是个对象,context如果为基本数据类型无法添加fn属性
            if(/^(symbol|bigINT)$/.test(type))){
                context=Object(context)
            }else{
                 context=new context.constructot(context) //如果是普通类型就直接通过其构造函数包装成一个对象类型
            }
        }

    let key=Symbole("key");
    context.key=this
    let result=context.key(..args)
    delete context.key
    return result

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
call、apply和bind都是用来改变函数中的this指向的方法。其中,call和apply可以直接调用函数并传递参数,而bind则返回一个新的函数,需要手动调用。 具体实现方案如下: - call的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数。 3. 结束调用后,删除该属性。 - apply实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数数组。 3. 结束调用后,删除该属性。 - bind的实现: 1. 创建一个新的函数,并将原函数作为其中的属性保存起来。 2. 当新函数被调用时,将之前绑定的对象作为this,并传递参数。 3. 返回新函数供后续调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [如何实现call、apply、bind](https://blog.csdn.net/XIAO_A_fighting/article/details/116701887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [原生JS实现 call apply bind](https://download.csdn.net/download/weixin_38628990/14046564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值