javascript中this的用法

251 阅读3分钟

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,默认对应的也是全局变量。

总结:

  1. 普通函数的调用,this指向的是window
  2. 对象方法的调用,this指的是该对象,且是最近的对象
  3. 构造函数的调用,this指的是实例化的新对象
  4. apply和call调用,this指向参数中的对象
  5. 定时器中的调用,this指向的是全局变量window
  6. 匿名函数的调用,this指向的是全局对象window