It has been 1485 days since the last update, the content of the article may be outdated.

定义

给xiaoming绑定一个age()方法:

javascript
>var xiaoming={
name:'xiaoming',
birth:1990,
age: function(){
var y= new Date().getFullYear() //
return y-this.birth
}
}

>xiaoming.age
//function(){
// var y= new Date().getFullYear()
// return y-this.birth
// }

>xiaoming.age() //28

方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量。
所以,this.birth可以拿到xiaoming的birth属性。
类似于python class 方法中的 self 参数

看一些例子:

javascript
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}

var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};

xiaoming.age(); // 28, 正常结果
getAge(); // NaN
  • 如果以对象的方法形式调用,比如 xiaoming.age(),该函数的 this 指向被调用的对象,也就是 xiaoming,这是符合我们预期的。
  • 单独调用函数 getAge() 返回 NaN,比如 getAge(),此时,该函数的 this 指向全局对象,也就是 window

要保证this指向正确,必须用obj.xxx()的形式调用!

javascript
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN

方法重构一下:

javascript
'use strict';

var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};

xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined

结果又报错了!原因是this指针只在age方法的函数内指向xiaoming,在函数内部定义的函数,this又指向undefined了!(在非strict模式下,它重新指向全局对象window!)

修复的办法也不是没有,我们用一个that变量首先捕获this:
javascript
'use strict';

var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var that = this; // 在方法内部一开始就捕获this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
return getAgeFromBirth();
}
};

xiaoming.age(); // 28

apply 和 call

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

javascript
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}

var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};

xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
  • apply()把参数打包成Array再传入;
  • call()把参数按顺序传入。
    javascript
    Math.max.apply(null, [3, 5, 4]); // 5
    Math.max.call(null, 3, 5, 4); // 5
    对普通函数调用,我们通常把this绑定为null。