手写call(),apply(),bind()方法

目录

知识储备:

一:手写call方法

1、思路

 2、实现

3、Symbol调优

二:手写apply方法

1、思路

2、实现

三:手写bind方法

1、思路

2、实现

 四:总结

知识储备:

所有的方法都可以调用我们手写的方法,因此需要挂载在原型上,因此我们使用以下代码进行挂载

Function.prototype.myCall = function () { console.log(' 方法执行 ') }

一:手写call方法

        call方法是改变this指向的一个常用方法,其写法是 func.call(thisArg,att1,att2,...) 。在这里第一个参数是我们要将this改变到哪个实例上,从第二个属性开始,就是我们要传递的参数。因为是直接传递的,所以我们这里不确定有几个参数,因此在重写的时候需要使用 ...args 来进行接收。同时在使用这个参数的时候需要 ...args 来进行结构。下面我们来整理一下思路以及实现吧。

1、思路

  • 定义myCall方法
  • 设置this并调用原函数
  • 接收剩余参数并返回结果

 2、实现

    

手写call(),apply(),bind()方法_第1张图片

3、Symbol调优

         在上面的代码中,我们可以看到,是使用的 thisArg.f 指向了 this 。但是这样有一个弊端,即你无法确定在 thisArg 中是否存在 f 方法,因此我们使用Symbol进行调优。将myCall()中的代码替换如下:

            //Symbol调优
            // 2. 设置this为原函数
            // thisArg 传入的设置为this的对象
            // 这里的this就是原函数  因为是  原函数.myCall()
            // 4. Symbol调优
            const key = Symbol('key')
            //这里是动态解析key
            thisArg[key] = this
            // 3. 接受剩余参数并返回结果
            const res =  thisArg[key](...args)
            // 因为添加了f属性所以要删掉
            delete thisArg[key]
            return res

        这里就不附加运行图了,最终的效果也是一样的哦!而且更为的安全可靠,推荐使用这种方法。

二:手写apply方法

        apply方法是另一种比较常见的改变this指向的方法,这个方法和call方法一样,都是在调用时改变this的指向,但是 apply 与 call 不同的地方在于,apply接收的第一个参数是thisArg(需要指向的对象),而第二个参数则是一个数组。apply只有这两个参数,这一点是区别于 call 方法的。其余的地方基本上是一样的。下面是实现思路以及具体代码。 

1、思路

  • 定义myApply方法
  • 设置this并调用原函数
  • 接收参数并返回结果

2、实现

        这个实现方法其实和myCall的实现方法很相近,不同的是接收参数的时候因为已经传的是数组了,所以我们不需要使用  ...  来接收不确定数量的参数,直接使用args就可以了。

    

手写call(),apply(),bind()方法_第2张图片

三:手写bind方法

        bind 方法是直接区别于 call 方法和 apply 方法的,该方法是在创建时就改变了this的指定,同时返回的是一个新的方法,在调用新方法的时候同样可以传参,这样会和之前方法的参数进行一个拼接合并。该方法不会改变原方法的this指向,具体思路以及实现见下。 

1、思路

  • 定义myBind方法
  • 返回绑定this的新函数
  • 合并绑定和新传入的参数

2、实现

    

手写call(),apply(),bind()方法_第3张图片

 四:总结

        call、apply、bind三个方法是改变this指向的重要方法,熟练的使用以及掌握其源码实现原理,能够帮助我们更好地理解和使用这三个方法。同时可以让我们在项目开发过程中规避掉很多不应该的错误,并且提高我们的逻辑思维能力。

        因此,学习这三个方法是很有必要性的。希望本文能够对各位小伙伴有所帮助哦~

你可能感兴趣的:(JavaScript,javascript,前端,开发语言)