this 的指向,始终坚持一个原理:this 永远指向最后调用它的那个对象
如果没有调用的对象,那么调用对象就是全局对象window。
需要注意的是,这里我们没有使用严格模式,如果使用严格模式的话,那么全局对象就是 undefined,就会报错 Uncaught TypeError: Cannot read property 'name' of undefined
下面我们来看一个简单的例子: 例 1:
var str = "hello";
function a() {
var str = "world";
console.log(this.str); // hello
function b() {
var str = "hello world";
console.log(this); //Window
}
b();
}
a();
console.log(this); //Window
首先看调用 a 的地方 a();因为a前面没有调用的对象,也就是相当于是 window.a(),即a的this指向了window
第一个console.log输出hello,因为this指向了window,所以this.str获取到的值就是window下的hello,而并不是a方法中的world
然后我们在a方法里面,又有定义了一个b方法,并且执行b方法
第二个console.log打印了b方法中的this
这个this其实还是指向window对象,虽然b在a的里面,但其实调用b方法的还是window对象
最后一个console.log打印的也是Window,因为实际上是Window.console.log
再看下这个例子: 例 2:
var str = "hello";
var a = {
str: "world",
fn : function () {
console.log(this.str); // world
}
}
a.fn();
在这个例子中,函数 fn 是对象 a 调用的,即this指向了a,所以打印的值就是 a 中的 str 的值。是不是有一点清晰了呢~
继续看下面这个例子
例 3:
var str = "hello";
var a = {
str: "world",
fn : function () {
console.log(this.str); // world
}
}
window.a.fn()
这里打印 world的原因也是因为我们之前说的那句话this 永远指向最后调用它的那个对象,这里也就是a
我们再来看一下这个例子: 例 4:
var str = "hello";
var a = {
// str: "world",
fn : function () {
console.log(this.str); // undefined
}
}
window.a.fn();
这里为什么会打印 undefined 呢?这是因为调用 fn 的是 a 对象,而对象 a 中并没有对 str 进行定义,所以我们打印的 this.str的值是undefined
这个例子还是说明了:this 永远指向最后调用它的那个对象,所以就算 a 中 没有 str 这个属性,也不会继续向上一个对象寻找 this.str,而是直接输出 undefined
最后看一个比较坑的例子: 例 5:
var str = "hello";
var a = {
str: "world",
fn : function () {
console.log(this.str); // hello
}
}
var f = a.fn;
f();
这里你可能又会有疑问,为什么不是 world?
这是因为虽然将 a 对象的 fn 方法赋值给变量 f 了,但是此时并没有调用, 而是通过fn()去调用的,而fn()是被 window 调用的。所以 this 指向的也就是 window
由以上五个例子我们可以看出,this 的指向并不是在创建的时候就可以确定的,**this 永远指向最后调用它的那个对象**。