传统JS指向(理解)
- this是在函数被调用时进行绑定的,指向谁完全取决于函数在哪里被调用。
- 亦即 this 的指向不是函数被创建时绑定,而是被怎么样的方式调用时绑定的
默认绑定
var name = 'window'; |
这里show()是直接不带任何修饰的函数调用,因此this会被默认绑定到window对象。
显示绑定(bind,apply,call)
var name = 'window'; |
此处show()的this通过aplly 、call、bind等方法绑定到obj对象
隐式绑定
(1)对象隐式绑定
var name = 'window'; |
虽然show()函数是在全局被创建,但被obj.show方法引用了。此时调用obj.show()方法,this被绑定给obj对象。
(2)DOM对象隐式绑定(了解)
var name = 'window'; |
当触发点击事件的时候,show()函数中的this被指向了oBtn(DOM)对象。
new 绑定
var name = 'window'; |
通过new赋值绑定。
ES6中箭头函数this指向(重点)
箭头函数this的定义:其this是在定义函数的时候绑定,而不是在执行函数的时候绑定。
扩充理解:
箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
所谓的定义时候绑定,就是this是继承自父执行上下文!!中的this。
var x = 11; |
这里的箭头函数中的this.x,箭头函数本身与say4平级以key:value的形式,也就是箭头函数本身所在的对象为obj,而obj的父执行上下文就是window,因此这里的this.x实际上表示的是window.x,因此输出的是11。(this只有在函数被调用,或者通过构造函数new Object()的形式才会有this)。
say(),say3()则是根据调用时的对象所决定的 –> obj.methods,obj。
say2(): 由于箭头函数的this继承的是父执行上下文里面的this,而简单对象(非函数)是没有执行上下文的,所以箭头函数里的this没有绑定obj,自然而然是绑定到window对象上了。如果这里的obj是函数,那么输出的就是22了
Vue 中this指向
var vm = new Vue({ |
先引用一句官方有关this解释:
所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义。
从上面可以看出:
data 中的this指向 window (其实一般也不会在data中操作this)
而生命周期函数(created/mounted/updated…)中会自动绑定至对应vue实例中,包括箭头函数
特别是在vue生命周期函数中我们用到回调函数(setTimeout/promise.then…)时经常使用箭头函数来确保当前this指向对应vue实例。
但是在定义对象方法、定义原型方法、定义构造函数、定义事件回调函数时不能使用箭头函数否则会指向window。
以上是个人根据ES6和网络上的资料整理加上个人理解整理,避免以后再次混淆则又查半天~
开心的是到此终于完全把this指向问题搞明白!!!