关于this指向,以及尝试对改变this指向(call(),apply(),bind())的函数的实现

1 篇文章 0 订阅
1 篇文章 0 订阅

一般情况下,函数中的this指向被调用的对象,如果函数被直接调用,则指向window。

但是有些方法是可以改变函数this指向的,例如call(),apply(),bind()

他们的相同点和不同点分别是:

call和apply在改变this指向时会执行函数,bind不会,它会返回一个新的函数,新的函数中的this指向会被改变

call和bind在传参上类似,都是将参数单独传递,而apply是将参数作为一个数组进行传递,但是bind能同时在外部和内部传参(与它返回的是一个新函数有关,外部传参就相当于在执行新函数时传参)

接下来就是我对这三种方法的源码的实现

call()

定义在Function的原型上就是为了函数调用的

target为传递的第一个参数,即函数的this的指向的对象,如果不传则为window。

arg为传递的参数除去第一个(即除去target后的所有参数)

...arg中的...为ES6的展开运算符

在target.fn=this中,这个this的指向在开头有讲过,this指向调用这个函数的对象,即调用call的函数(简称fun),但是如果直接执行fun,那么fun的this指向window,显然是不行的,所以我们在target上添加一个属性为fn,fn为fun,然后再用执行target.fn间接执行fun,此时因为是被target打点调用,所以this指向target。

最后一步为删除target上的fn属性,不然target会多出一个属性,这显然是不太合适的,所以直接调用delete方法删除这个属性

想要理解这里就只需要谨记一点,this指向被调用的对象,如果函数被直接调用,那么就指向window(可以理解为直接调用就是被window调用)

Function.prototype.myCall = function () {
            var target = arguments[0] || window;
            var arg = Array.from(arguments).slice(1);
            target.fn = this;
            target.fn(...arg);
            delete target.fn
        }

如果理解了call(),那么apply就好理解了,因为它与call()的区别就在于传参的形式不同

        Function.prototype.myApply = function () {
            var target = arguments[0] || window;
            var arg = arguments[1];
            target.fn = this;
            target.fn(...arg);
            delete target.fn
        }

bind因为返回值不同,所以它是最为难理解的一个

这个new.target为检测函数或构造方法是否是通过new运算符被调用的,此处也是为了迎合bind被调用的不同场景下的不同返回值,刚开始看着可能会比较不明白,只需要多尝试,去掉判断条件将bind与myBind 在被new时进行对比就能知道含义了

        Function.prototype.myBind = function () {
            var target = arguments[0] || window;
            var arg = Array.from(arguments).slice(1);
            var that = this;
            return function () {
                if (!new.target) {
                    var args = arg.concat(Array.from(arguments));
                    target.fn = that;
                    target.fn(...args);
                    delete target.fn;
                } else {
                    return new that();
                }
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值