This的指向问题一直是JavaScript的一大核心,很多人都是觉得了解了,但是又模模糊糊。简单概括就是,this的指向永远是指向调用这个this的对象。下面介绍几个本人理解的this指向问题。
代码语言:javascript复制var a = 10;
console.log(this.a);
alert(this.a);
这是最简单的this指向问题,console.log()和alert()是两个函数,是window的函数
var a = 10;
window.console.log(this.a);
window.alert(this.a);
所以调用函数的对象是window,this也就是指向window。
var a = 10;
function fun() {
var a = 100;
console.log(this.a);
}
fun();相当于window.fun();
这段代码一样的,因为函数的调用对象是window,所以this还是指向window
var a = 10;
var obj = {
a: 100,
b: function () {
console.log(this.a);
}
};
obj.b();
可以看见,b方法是对象obj里面的方法,那么调用b方法的对象就是obj,这时的this指向就是指向obj,所以输出的是100。
var a = 10;
function fun() {
this.a = 100;
}
var obj = new fun();
console.log(obj.a);
同样的,这边的输出也是100,因为调用a的是obj对象,this指向obj,那么这边的a就是100。
var a = 10;
function fun() {
var a = 10000;
}
var obj = new fun();
console.log(obj.a);
还记得原型链吗,如果是这样调用,那么输出undefined,因为obj没有定义a,要增加这个a就要函数里面用this增加或者用prototype。
接下来就是改变this指向的两个方法,call和apply,两个都是改变this的指向,只是参数不同,两个方法的第一个参数都是想要改变this指向的对象,call除了第一个参数外,剩下的都是方法的参数,apply除了第一个参数外,只能是再加一个数组,数组里面的每一项都是方法的参数。
var a = 10;
var a = 10;
var obj = {
a: 100,
b: function () {
console.log(this.a);
}
};
obj.b.apply();
obj.b.call();
输出的都是10,因为没穿参数,默认把window传进去了,所以this的指向变成了window,b方法输出的就是10。
var a = 10;
var obj = {
a: 100,
b: function (x, y) {
console.log(x);
console.log(y);
}
};
obj.b.apply(window, [1, 2]);
obj.b.call(window, 1, 2);
当要传参数的时候,第一个就必须是指定的对象,call之后的参数就是方法的参数,apply数组的参数就是方法的参数。
var a = 10;
var obj = {
a: 100,
b: function () {
console.log(this.a)
}
};
var objChange = {
a: 10000
}
obj.b.apply(objChange);
obj.b.call(objChange);
Call和apply传入的第一个参数,就是this改变后指向的对象,所以这边输出的都是10000。
还有一种特殊情况,那就是定时器和计时器
var a = 10;
var obj = {
a: 100,
b: function () {
console.log(this.a);
setTimeout(function () {
console.log(this.a);
},1000);
}
};
obj.b();
第一个输出是100,定时器输出的是10,这是因为定时器和计时器是属于window的方法,那么这时候的this就是指向window。