JavaScript call apply bind中this的问题以及内部代码实现过程

谈论JavaScipt中call apply bind,我们当然首先需要探讨的就是this的指向问题了

在 ES5 中,其实 this 的指向,始终坚持一个原理:this 永远指向最后调用它的那个对象(看完所有例子,有补充部分的特殊情况)
例1:默认绑定
JavaScript call apply bind中this的问题以及内部代码实现过程_第1张图片
根据刚刚的那句话“this永远指向最后调用它的那个对象”,我们看调用 thisIndex()的地方;,前面没有调用的对象那么就是全局对象 window,这就相当于是 window.thisIndex();注意,这里我们没有使用严格模式,如果使用严格模式的话,全局对象就是 undefined

例2:同上
JavaScript call apply bind中this的问题以及内部代码实现过程_第2张图片

例3:隐式绑定
JavaScript call apply bind中this的问题以及内部代码实现过程_第3张图片
这里打印 function的原因也是因为刚刚那句话“this 永远指向最后调用它的那个对象”,最后调用它的对象是对象 a,相当于window.a.fn()

例4:隐式丢失=》默认绑定
JavaScript call apply bind中this的问题以及内部代码实现过程_第4张图片

这里你可能会有疑问,为什么不是 function,这是因为虽然将 a 对象的 fn 方法赋值给变量 f 了,但是没有调用,记住“this永远指向最后调用它的那个对象”,由于刚刚的 f 并没有调用,所以 fn() 最后仍然是被 window 调用的,即window.f()

以上例子我们可以看出,this的指向并不是在创建的时候就可以确定的,在 es5 中,this永远指向最后调用它的那个对象

补充:important!!!

例5:绑定例外
JavaScript call apply bind中this的问题以及内部代码实现过程_第5张图片
JavaScript call apply bind中this的问题以及内部代码实现过程_第6张图片
嗯???为什么是18???其实把函数执行的位置捋清楚也是符合规则的。
首先,showAge函数定义在一个对象中,里面有个定时器setTimeout,定时器等待300毫秒后执行打印操作,这应该没问题。
然后,在外面执行obj.showAge(),所以showAge里的this指向obj。在定时器中,作为回调函数的callback只是单纯地在符合条件后执行了,那么,这里的callback函数是不是没有被谁打点调用,所以该函数的this应该指向全局对象window。所以打印的就是全局的age,等于18。
同时也可以得到一个普遍的结论:一般的回调函数(立即执行函数,return函数等)的this指向全局对象window

改变this 的指向的方法:

1.使用 ES6 的箭头函数:

箭头函数拥有词法作用域的this值(即不会新产生自己作用域下的this, arguments, super 和 new.target 等对象)
也就是说箭头函数本身不具有this,它会直接绑定到它的词法作用域内的this,也就是定义它时的作用域内的this值。所以试图使用apply,call等方法修改箭头函数的this是不会成功的,因为箭头函数自身没有this。

例1:
:JavaScript call apply bind中this的问题以及内部代码实现过程_第7张图片
例2:
JavaScript call apply bind中this的问题以及内部代码实现过程_第8张图片

箭头函数this总是指向该函数定义生效时所在的对象
例3:
JavaScript call apply bind中this的问题以及内部代码实现过程_第9张图片
例4:
JavaScript call apply bind中this的问题以及内部代码实现过程_第10张图片

2. 使用 apply、call、bind,显式绑定

先简单说一下call apply bind 的作用和使用方法:

call apply 都是改变一个函数的this指向并执行该函数,区别是传参列表不同,call(obj, 参数1, 参数2, …) apply(obj, arguments)

bind是改变一个函数的this指向并返回一个新的函数,传参结合call和apply的,只接收第一次绑定的this

例1:模拟call方法自定义一个myCall代码:
JavaScript call apply bind中this的问题以及内部代码实现过程_第11张图片

例2:模拟bind方法自定义一个myBind代码:
JavaScript call apply bind中this的问题以及内部代码实现过程_第12张图片

3.new绑定

new绑定可以参考我的上一篇文章

结语:

默认绑定,隐式绑定,显式绑定,new绑定的this 绑定四条规则,实现过程还是得大家好好理解,希望有错误的地方大家多多指正,纯属个人理解。

你可能感兴趣的:(JS)