Fork me on GitHub

浅谈JavaScript中this

作为函数调用

this关键字指定的对象取决于函数的调用方式,JavaScript 中的函数的调用有以下几种方式:

  • 作为函数调用
  • 作为对象方法调用
  • 作为构造函数调用
1
2
3
4
5
6
7
8
9
10
11
var n = "Hello World!";
function example(){
console.log(this.n);
}
example(); //Hello World!
var n = 'Hello World!';
function example(){
this.n=0;
}
example();
console.log(n); //0

结论:当函数直接调用时,该函数的this关键字指向的就是全局对象window。

作为对象方法调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var zhangsan = {
name: '张三',
birth: 1990,
age: getAge
};
console.log(zhangsan.age());//27
console.log(getAge()); //NaN
var fn = zhangsan.age;
console.log(fn()); //NaN
var name = 'Akita';
var dogs = {
name:'Collie',
showName: function(){
console.log(this.name);
}
};
console.log(dogs.showName()); //Collie
var otherNmae = dogs.showName;
console.log(otherName()); //Akita

结论:当使用obj.xxx()的形式调用函数时,里面的this关键字指向的就是对象本身。但是需要注意:在对象方法内部再次定义一个方法,该方法的this关键字又会重新指向全局对象window!这点需要特别注意比如下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
var zhangsan = {
name: '张三',
birth: 1990,
age: function(){
function getAgeFromBirth(){
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};
console.log(zhangsan.age()); //NaN

在 strict 模式下你会得到的错误就不是 NaN,而是TypeError:Cannot read property ‘birth’ of undefined。

作为构造函数调用

1
2
3
4
5
function Student(name){
this.name=name;
}
var xiaoming = new Student('小明');
console.log(xiaoming.name); //小明

指定 this 指向

指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。

1
2
3
4
5
6
7
8
9
10
11
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '张三',
birth: 1990,
age: getAge
};
zhangsan.age(); // 25
getAge.apply(zhangsan, []); // 25

利用apply()将getAge()的this指向了xiaoming这个对象,因此函数执行正确。

据说帅的人都赏给博主几块钱零花钱。