目前在复数视频上观看“高级Javascript”。在课程的“面向对象”部分,Kyle让我完全失去了一个部分:
NotesManager.prototype.showHelp = function() {
this.$help.show();
document.addEventListener("click",function() __handler__(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
document.removeEventListener("click", __handler__,true);
this.hideHelp();
},true);
};
this
引用现在将成为导致this.hideHelp();
无效的按钮。他首先尝试使用硬绑定解决方案来解决问题:
NotesManager.prototype.showHelp = function() {
this.$help.show();
document.addEventListener("click",function() __handler__(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
document.removeEventListener("click", __handler__,true);
this.hideHelp();
}.bind(this),true);
};
他所说的解决了this
问题但导致了另一个问题。上面使用了一个命名函数,因此它可以解除绑定。但是他说这个函数的名称不是现在绑定的。绑定的函数是新的硬绑定函数,因此它不能解除绑定,因为我们没有对硬绑定函数的引用。咦?谁能解释一下。他没有详细说明。
之后,他解释了解决问题的最佳方法是使用自引用:
NotesManager.prototype.showHelp = function() {
var self = this;
self.$help.show();
document.addEventListener("click",function() __handler__(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
document.removeEventListener("click", __handler__,true);
self.hideHelp();
},true);
};
通常他说他建议避免这样做,因为它表明代码味道,但他说这是最好的解决方案之一。他继续说你自己在脚下射击,因为你很难实施this
机制,然后你又回到了词汇范围。他说,使用自我引用的人通常不了解这些机制是如何工作的。我从来没有听说过自我引用是一种代码味道。我见过它广泛使用。为什么一般表示代码味?也许它应该只在你有一个事件处理程序时使用?
答案 0 :(得分:1)
这是Javascript中常见的范围问题,新的胖箭头符号应该有所帮助。根据我的经验,每个人都讨厌使用self = this
,但无论如何都要这样做 - 主要是因为它保持可读性。
胖箭头符号对此问题有很大帮助,并且使用 self
进行介绍会导致成为代码异味。
在箭头函数之前,每个新函数都定义了自己的
this
值 (构造函数中的新对象,在严格模式下未定义) 函数调用,如果函数被调用为上下文对象 “对象方法”等)。事实证明这很烦人 面向对象的编程风格。
- MDN(Code
强调我的。)
答案 1 :(得分:-1)
修改:将lexical
范围更改为functional
范围
为什么它被认为是代码味道的原因是因为JavaScript中的所有东西都是功能范围的。但是,this
是动态范围的。
void foo()
{
int floo = 1;
void foo2()
{
console.log(floo);
}
}
每个内在级别都可以访问外层。
但与this
相反,它不能做到这一点。
void foo()
{
//this refers to foo()
console.log(this)
void foo2()
{ //this refers to foo2()
console.log(this);
}
}
人们可能会感到困惑,但对我来说这并不是什么大不了的事。