浅谈JS中this关键字指向的对象

学习js三个月了,现在来谈一下this关键字,做个总结。

java中的this

因为之前是码java的,所以我想和之前的OO语言做个比较。所以如果之前你敲过java,对这样的代码应该不会陌生:

1
2
3
4
5
6
7
public class Test1{
private int i=1;
public void Test1(){
this.i++; //①这里的this指向什么?
}
}

当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this。上个例子中,如果你创建了一个Test的实例对象,那它就是Test对象的引用。

当然还有这样的:

1
2
3
4
5
6
7
8
9
10
11
public class Test2{
private int i=1;
public void Test2(){
this(2); //②这里的this用来干嘛?
}
public void Test2(int i){
this.i++;
}
}

这个例子是用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。

js中的this

因为之前的概念,所以搞了很久才接受js中的this。总之,就是一句话,关键字 this 总是指向调用该方法的对象。这句话,看上去很简单,但我想举几个例子,以便有个更好的记忆。

  • example 1:
1
2
3
4
5
function Person(){
this.name="wtf"; //①这里的this指的是什么?
}
Person();
  • example 2:
1
2
3
4
5
6
7
var Person= {
hehe:function () {
this.name="wtf"; //②这里的this指的是什么?
}
};
Person.hehe();
  • example 3:
1
2
3
4
5
6
7
function Person() {
this.name = "wtf"; //③这里的this指的是什么?
}
var person = new Person();
console.log(person.name);
  • example 4:
1
2
3
4
5
function hehe() {
console.log(this.name); //④这里的this指的是什么?
}
node.addEventListener('click',hehe);
  • example 5:
1
2
3
4
5
6
7
8
9
var Person = {
name: 'wtf',
hehe: function () {
console.log(this.name); //⑤这里的this指的是什么?
}
};
node.addEventListener('click',Person.hehe);
  • example 6:
1
2
3
4
5
6
7
8
9
10
11
var Person = {
name: 'wtf',
hehe: function () {
console.log(this.name); //⑥这里的this指的是什么?
}
};
node.addEventListener('click', function () {
Person.hehe();
});

先说一下答案:

  1. global
  2. Object
  3. Person
  4. global
  5. global
  6. Object

始终记住一句话,关键字 this 总是指向调用该方法的对象!你可以像记右手法则来记它,并用它来判断。

  • 首先看第一个,你可以理解为无人调用它(函数调用),如果无人调用,那它指的就是global,就这样。

  • 第二个,因为是Person调用了hehe方法(方法调用),Person是一个Object,所以是Object,完毕。

  • 第三个,new关键字来了,其实new关键字是做了一些工作的,这里简单说一下,比如var person =new Person(),那么它其实这样做了:

    1
    2
    3
    4
    var Person=function () {
    this=Object.create(Person.prototype); //new的时候创建一个Person的原型对象并返回
    return this;
    };

可能你会问怎么能允许给this赋值呢?是的,我们没有这样的能力,但js的解释器是有这样的能力的。
所以答案是Person

  • 第四个,放到一个事件方法里了,有些可能就以为有些“猫腻”了,甚至觉得指向node=。=,其实前面加再多都没卵用,始终一句话,this 总是指向调用该方法的对象。无人调用(函数调用)hehe,那就是global

  • 第五个,还是在一个事件方法里,只不过,hehe前面加了个Person.。所以如果觉得这里的this指的是Person的话,还是先去把方法方法被调用这两个概念搞清楚。之前码java的,都没接触过方法可以作为参数,但Person.hehePerson.hehe()不是一码事。

  • 最后一个,也许就是就是上一个例子里,你想要的答案=。=,这次不是直接写了,而是放到一个function内,再由Person来调用hehe,这次,没得说了吧,this指的就是Object了。

说了这些,其实都不如这一句话,this 总是指向调用该方法的对象。