this引用问题
JavaScript的对象也可以为其定义方法;
方法与函数不同之处在于,方法可以通过this来引用对象中的属性和其他方法;1
2
3
4
5
6
7
8
9
10
11var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年调用是25,明年调用就变成26了
在JavaScript中存在一个问题,this具体指向谁需要视情况而定!
1 | function getAge() { |
方法必须通过obj.xxx()进行调用才能确保this引用正常!
1
2
3 var fn = xiaoming.age; // 先拿到xiaoming的age函数
// 这里调用fn()还是window
fn(); // NaN
即使是在对象内部也无法保证能够正常的引用到this引用!
1 | var xiaoming = { |
strict模式下函数的this不再指向window,而是指向undefined!
1 | 'use strict'; |
捕获this引用,解决闭包函数this引用问题!
1 | 'use strict'; |
apply方法修复this指向
函数的this默认是指向window或undefined(strict mode),但是我们可以通过apply来控制其指向;
apply方法接收两个参数,一个指定要绑定的this变量,另一个则是传递给函数的参数数组;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
// 为getAge函数绑定xiaoming变量为this
// 因为getAge不需要参数,所以此处传递一个空数组;
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
call方法与apply方法类似,不同在于,call传递给函数的参数是直接按顺序传入的,而apply则是通过数组进行传递;
1 | // 如果函数不需要绑定this变量,则默认传入null |
apply和call只有在函数没有绑定this作用域的情况下才能起作用,如果已经绑定了,则绑定的this会被忽略掉。
箭头函数的this作用域绑定了所在语境的作用域,此时重新为其绑定的this将被忽略。1
2
3
4
5
6
7
8
9
10var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = (y) => y - this.birth; // this.birth仍是1990
// 重新绑定的this无效,仍然是obj
return fn.call({birth:2000}, year);
}
};
obj.getAge(2015); // 25
apply方法实现装饰器
在JavaScript中,所有的对象都是动态的,即使是系统内置的函数,我们也可以对其进行重新赋值!
利用apply方法可以动态修改函数的特点,我们可以对内置函数进行包装,实现装饰器:
1 | 'use strict'; |