JavaScript中this指向问题

JavaScript中this指向问题

记得初学 JavaScript 时,其中 this 的指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称 JS 武林中的三大魔头。若是你要想在 JS 武林中称霸一方,必须将这三大魔头击倒。我的认为在这三大魔头中,this 指向问题的武功最菜(难度最低)。俗话说柿子捡软的捏,那咱们就先从 this 指向问题下手。javascript

先记住攻克 this 指向问题的口诀(前辈们的总结):哪一个对象调用函数,函数里的 this 就默认指向哪一个对象(注意 this 只能指向对象)。这里说“默认指向”是由于咱们经过箭头函数、call、apply、bind等手段来改变 this 的指向。如今咱们只讨论 this 的默认指向。java

全局做用域下以及全局做用域的函数中,this默认指向全局对象window

在严格模式下,全局做用域的函数中,this默认指向 undefined, 这是严格模式所规定的。闭包

// 非严格模式下
console.log(this); // Window
function doSomething(){
    console.log(this); // Window
}
doSomething(); // 这里能够当作window.doSomething(),因此函数里的this指向全局对象window
// 严格模式下
'use strict';
console.log(this); // Window
function doInStrict(){
    console.log(this); // undefined
}
doInStrict();

对象里的函数,this指向该对象

var a = 1;
var obj = {
    a: 2,
    fn: function(){
        console.log(this); // {a: 2, fn: ƒ}
        console.log(this.a); // 2
    }
};
obj.fn();

上面函数被调用后,从打印结果能够看出此时 this 指向的是调用函数的对象 obj。若是将对象中的函数赋给全局对象中定义的变量 fn1,执行 fn1 又会出现什么结果呢?app

var a = 1;
var obj = {
    a: 2,
    fn: function(){
        console.log(this); // Winidow
        console.log(this.a); // 1
    }
};
var fn1 = obj.fn;
fn1(); // 能够当作window.fn1();

从上面的例子能够看出,fn1 与 obj.fn 指向的函数是相同的,可是调用它的对象不一样,那么函数中 this 的指向也就不同了。函数

再看一个比较复杂的例子:this

var a = 0;
function fn(){
	consoloe.log(this.a);
}
var obj1 = {
	a: 1,
	fn: function(){
		console.log(this.a);
	}
};
var obj2 = {
	a: 2,
	fn: function(){
		fn();
		obj1.fn();
		console.log(this.a);
	}
}
obj2.fn();

先说下执行结果,分别打印 0 1 2。当 obj2 调用 fn 函数时,先执行的是 fn(),这个函数是在全局做用域中定义的,该调用能够当作 window.fn(),因此,该函数内部的 this 指向的是 window 全局对象,this.a 天然就是全局对象中的 a 值(0)。code

接着执行的是 obj1.fn(),它会从 obj1 中找到 fn 函数并执行。obj1 中的函数 fn 执行时调用它的对象是 obj1,因此,此时函数内部的 this 指向的就是 obj1 自身。那么 this.a 查到的值也就是对象 obj1 中 a 的值(1)。对象

最后打印函数中 this 所处的函数 fn 是被 obj2 调用的,那么天然而然 this 就指向了 obj2,因此 this.a 的结果就是 2 了。ip

从上面这个例子咱们能够看出:函数内部 this 指向跟调用函数的对象有关,跟函数在哪里调用没有关系。原型链

Window内置函数的回调函数中,this指向Window对象。

window 的内置函数( setInterval setTimeout 等),其回调函数中的 this 指向的是window对象。

var name = 'window';
var obj = {
    name: 'obj',
    func: function(){
        setTimeout(function () {
            console.log(this.name) // window
        },1000)
    }
}

obj.func()

可是通常在开发中,不少场景都须要改变 this 的指向。 后面我会专门写一篇关于更改 this 指向的文章,这里就再也不赘述了。

相关文章
相关标签/搜索