我知道有关箭头函数的主题已经讨论了很多,但找不到以下用例的答案。
这个例子来自Angular 4 Directive:
export class MouseParallaxDirective implements AfterViewInit {
constructor(private element: ElementRef) {
}
ngAfterViewInit() {
// Here `this` points at the angular component object
let movementStrength = 25;
let height = movementStrength / window.innerHeight;
let width = movementStrength / window.innerWidth;
let parallaxElement = this.element.nativeElement;
window.onmousemove = (e) => {
// Here `this` points at the `window` object
let pageX = e.pageX - (window.innerWidth / 2);
let pageY = e.pageY - (window.innerHeight / 2);
let newvalueX = width * pageX * -1 - 25;
let newvalueY = height * pageY * -1 - 50;
parallaxElement.style.backgroundPosition = newvalueX +"px " + newvalueY + "px";
};
}
}
箭头函数保留外部范围后,两个this
是否都不应指向同一个对象?
答案 0 :(得分:2)
ngAfterViewInit
方法是从MouseParallaxDirective
class
的实例调用的,这基本上就是幕后的原型模式。
这意味着this
将引用class
实例。
this
上下文是以动态方式定义的,我们实际上应该问我们自己"什么是调用对象?"
确定this
的上下文有四个规则:
this
将是窗口对象(仅限于没有
strict mode
)。 When a function is called by a preceding dot,即:
myObj.myFunc()
该点之前的对象为this
(在这种情况下为myObj === this
)。
当我们使用.call
,.apply
或.bind
,this
is explicitly
defined时。
new
关键字),this
指的是创建的对象的特定实例
由constructor
函数返回。 自ES2015 以来,Arrow functions使用了不同的机制,this
不再以动态方式定义。
this
保留了封闭 LEXICAL 上下文的价值......
顺便说一句,这就是我们在向原型添加功能时不能使用箭头功能的原因,因为我们无法正确使用this
。
例如,从不执行此模式:
Array.prototype.mySort = () => {// this is not referenced to the array}
在您的情况下,window.onmousemove
的匿名箭头函数将引用class
实例,因为这是它的词汇上下文。
答案 1 :(得分:1)
方法onmousemove
属于窗口对象,因此在此函数内this
将引用窗口对象。
ngAfterViewInit
范围内声明的函数MouseParallaxDirective
,相同,这就是为什么在这种情况下,this引用该组件。
所以这种情况下的两个this
不能引用同一个对象。
但您仍然可以访问外部作用域,如此处所示,当在组件内声明变量时,我们可以在onmousemove
函数内访问它。
我们可以看到创建_this
以访问组件范围
<强>作用域:强>
演示: