this是 JavaScript 语言的一个关键字,函数调用时才会出现。
因为函数是在一定的环境中运行的,调用函数时肯定需要知道是[谁调用的]?就用到了this进行指向; 那么this到底指向的是什么?
this 既不指向函数自身,也不指函数的词法作用域,而是调用函数时的对象!它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
function test() {
this.x = 1;
}
上面代码中,函数test运行时,内部会自动有一个this对象可以使用。
那么,this的值是什么呢?
函数的不同使用场合,this有不同的值。总的来说,this就是函数运行时所在的环境对象。下面分六种情况,详细讨论this的用法。
情况一:纯函数调用
这是函数的最通常用法,属于全局性调用,因此this就代表全局对象。请看下面这段代码,它的运行结果是6。
var x = 6;
function test() {
console.log(this.x);
}
test(); // 6
情况二:作为对象方法的调用
函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
function test() {
console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test;
obj.m(); // 1
情况三 作为构造函数调用
所谓构造函数,就是通过这个函数,可以生成一个新对象。这时,this就指这个新对象。
function test() {
this.x = 1;
}
var obj = new test();
obj.x // 1
运行结果为1。为了表明这时this不是全局对象,可以对代码做一些改变:
var x = 2;
function test() {
this.x = 1;
}
var obj = new test();
x // 2
运行结果为2,表明全局变量x的值根本没变。
情况四 apply和call调用时,this指向参数中的对象
apply()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数。
var x = 0;
function test() {
console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test;
obj.m.apply() // 0
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
obj.m.apply(obj); //1
运行结果就变成了1,证明了这时this代表的是对象obj。
var name = '有鱼';
function eat(){
console.log(this.name);
}
var cat = {
name:'年年',
}
var dog = {
name:'高飞',
}
eat.call(cat);// 年年
eat.call(dog);// 高飞
apply方法和call方法相当于改变了显式的修改了prototype原型。
情形五 定时器中调用,指向的是全局变量
常用的定时器有setInterval和setTimeout,拿setInterval举例子:
var name = '卡卡';
var cat = setInterval(function(){
var name = '有鱼';
console.log(this.name);// 卡卡
clearInterval(cat);
},500);
其实定时器的本质,也是一种匿名函数的形式。
情形六 (五)匿名函数调用,指向的是全局对象
var name = '卡卡';
var cat = {
name:'有鱼',
eat:(function(){
console.log(this.name);//卡卡
})()
}
cat.eat;
这里提一下匿名函数调用方式,常用的有三种方法:
//①先用()包起来,然后再后面跟 (参数)
(function(data){
console.log(data);
})("222");
//②先后面跟(参数),然后再()包起来
(function(data){
console.log(data);
}("333"));
//③正常函数格式,前面加 !
!function(data){
console.log(data);
}("444");
箭头函数若使用this,默认对应的也是全局变量。
总结:
- 普通函数的调用,this指向的是window
- 对象方法的调用,this指的是该对象,且是最近的对象
- 构造函数的调用,this指的是实例化的新对象
- apply和call调用,this指向参数中的对象
- 定时器中的调用,this指向的是全局变量window
- 匿名函数的调用,this指向的是全局对象window