单拿出这一节详细说一下箭头函数(也就是lambda表达式)在TypeScript中的用法.
lambda表达式(()=>{something}
或()=>something
)相当于js中的函数,它的好处是可以自动将函数中的this
附加到上下文中.具体原理下面会讲到. (在其它js的函数库中基本都有绑定this到上下文的方法,如jQuery中的 proxy函数.)
例如:
function Arrow(age){
this.age = age;
this.add= function(){
this.age ++;
console.log(this.age);
}
}
var arrow2 = new Arrow(10);
setTimeout(arrow2.add, 1000); //期望值为11, 结果却是NaN.
原因是setTimeout执行的上下文环境为window,使得add方法中的this脱离了原上下文而指向了window.
现在对上例子使用箭头函数改造一下
function Arrow1(age){
this.age = age;
this.add= ()=>{
this.age ++;
console.log(this.age);
}
}
var arrow2 = new Arrow1(10);
setTimeout(arrow2.add, 1000); //11, 结果正确
打开ts编译后的js代码
function Arrow1(age) {
var _this = this; //自动创建了一个_this变量,指向了当前上下文.
this.age = age;
this.add = function () {
_this.age++; //在这里程序使用的是之前创建的_this中保存的上下文环境,而不是`this`
console.log(_this.age);
};
}
var arrow2 = new Arrow1(10);
setTimeout(arrow2.add, 1000);
这下我就知道为何使用箭头函数后得出正确的结果了.
现在我们可以把上面的例子变的更typescript一些.
class Arrow{
constructor(public age:number){}
add = ()=>{
this.age ++;
console.log(this.age);
}
}
var arrow = new Arrow(10);
setTimeout(arrow.add, 1000); // 11
注意: 箭头函数中的陷阱
1. 如果你想使用this
为当前调用时的上下文时不要使用箭头函数.因为箭头函数会把this
绑定到定义函数时的上下文环境.
2. 如果你正使用一些回调函数时请小心使用箭头函数.例如 jquery, underscore, 等. 这些函数库通常在回调函数中指明了this特殊意义如jquery中简单的each方法
$("li").each(function(){
alert($(this).text())
});
上例中的this实际代表每个li的dom对象,如果使用箭头函数则会得到错误结果,在者一般回调函数会在回调方法中放置参数(arguments)还是用each举例$(selector).each(function(index,element))
,如果你想使用index
或element
这些参数,也请不要使用箭头函数.还是直接写function吧,可以这么使用:
let _self = this;
something.each(function(){
console.log(_self); // 定义方法时的上下文
console.log(this); // 运行时另种库指定的上下文
});