this指向是动态的
想要理解this,你可以先记住以下两点:
1:this永远指向一个对象;
2:this的指向完全取决于函数调用的位置;
针对以上的第一点特别好理解,不管在什么地方使用this,它必然会指向某个对象;确定了第一点后,也引出了一个问题,就是this使用的地方到底在哪里,而第二点就解释了这个问题,但关键是在JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行,而this就是函数运行时所在的对象(环境)。这本来并不会让我们糊涂,但是JavaScript支持运行环境动态切换,也就是说,this的指向是动态的,很难事先确定到底指向哪个对象,这才是最让我们感到困惑的地方。
例子1:
上述代码中,fun函数被调用了两次,显而易见的是两次的结果不一样;很多人都会这样解释,obj.f()的调用中,因为运行环境在obj对象内,因此函数中的this指向对象obj;而在全局作用域下调用 fun() ,函数中的 this 就会指向全局作用域对象window。严格模式下,this的指向是undefined。
例子2:
上面代码中,A.f属性被赋给B.f,也就是A对象将匿名函数的 地址 赋值给B对象;那么在调用时,函数分别根据运行环境的不同,指向对象A和B。
例子3:
obj1对象的o1属性值是obj2对象的地址,而obj2对象的fn属性的值是函数foo的地址;函数foo的调用环境是在obj2中的,因此this指向对象obj2。
例子4:
例子5:
打印结果如下:
例子6:
例子7:
this指向总结:
1.非严格模式下,全局作用域下,普通函数的this指向window,严格模式下this指向undefined,如例子1。
2.构造函数调用,此时this指向实例对象,如例子4。
3.对象方法调用, 此时 this 指向 该方法所属的对象,如例子2,例子3和例子5。
4.通过事件绑定的方法, 此时this指向绑定事件的对象,如例子7。
5.定时器函数,此时this指向window,如例子6。
6.如果想修改this指向,可以用函数的bind,call或apply方法,他们的使用参考我之前写的<<函数call、apply与bind方法之间的区别>>
思考:如下代码中的两个this分别指向什么?
在非严格模式下,结果如下:
如果在严格模式,例如:
严格模式下打印结果如下:
那非严格模式下,如何让函数里的那个函数fn也能使用当前obj这个对象了,比喻说要在fn里输出name的值,该怎么写?
第一种方法:用一个变量把this保存起来
第二种方法:用箭头函数解决