Javascript `var self=this`是否被视为代码气味?
目前正在pluralsight上观看“高级Javascript”。在本课程的“面向对象”部分,有一部分Kyle让我完全迷失了方向:Javascript `var self=this`是否被视为代码气味?,javascript,Javascript,目前正在pluralsight上观看“高级Javascript”。在本课程的“面向对象”部分,有一部分Kyle让我完全迷失了方向: NotesManager.prototype.showHelp = function() { this.$help.show(); document.addEventListener("click",function() __handler__(evt) { evt.preventDefault(); evt.sto
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);
};
他说,它修复了这个问题,但导致了另一个问题。上面使用了一个命名函数,因此可以解除绑定。但他表示,函数的名称并不是现在定义的名称。被绑定的函数是新的硬绑定函数,因此它不能被解除绑定,因为我们没有硬绑定函数的引用。嗯?谁能解释一下。他没有详细说明
紧接着,他解释了解决问题的最佳方法是使用自我参考:
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);
};
通常,他说他建议避免这样做,因为这表明代码有异味,但他说这是一种罕见的情况,是最好的解决方案。他接着说,你开枪打自己的脚是因为你在实现这个机制时遇到了麻烦,然后又回到了词汇范围。他说,使用自我参照的人通常不了解这些机制是如何工作的。我从来没有听说过自我参照是一种代码气味。我见过它被广泛使用。为什么它通常表示代码气味?也许只有当您有事件处理程序时才应该使用它 这是Javascript中常见的作用域问题,新的胖箭头符号应该有助于解决这一问题。根据我的经验,每个人都讨厌使用self=this
,但无论如何都会这样做——主要是因为它保持可读性
胖箭头符号将极大地帮助解决这个问题,随着它的引入,使用self
正在成为一种代码气味
在arrow函数起作用之前,每个新函数都定义了自己的值
(如果是构造函数,则为新对象,在严格模式下未定义)
函数调用,如果函数作为
“对象方法”等)。这被证明是令人讨厌的
面向对象的编程风格
-(code
emphasis mine。)编辑:将词法范围更改为功能范围
之所以可以将其视为代码气味,是因为JavaScript中的所有内容都是功能范围的。但是,这个
是动态范围的
void foo()
{
int floo = 1;
void foo2()
{
console.log(floo);
}
}
每个内部级别都可以访问外部级别
但是对于这个
它是相反的,它不能这样做
void foo()
{
//this refers to foo()
console.log(this)
void foo2()
{ //this refers to foo2()
console.log(this);
}
}
人们可能会感到困惑,但对我来说这没什么大不了的。.bind
返回一个新函数,do\uu handler\uu.bind(this)!=__处理程序
。至于其余的,这只是一个人的意见。他可以很容易地使用var\uuuuu handler\uuuuu=function(evt){…}.bind(this)代码>您是否有任何来源支持您的主张,或者这只是您的观点?根据定义,代码气味是主观的,除非您在特定的范例下操作。我几乎以基于意见的方式投票结束了这个问题,但我相信代码气味是一个重要的话题,它绕过了SO基于意见的标志。如果你有激情,请投票决定是否结束。好的,谢谢你的解释。您编写的代码不是有效的JavaScript。2.JavaScript具有功能范围,而不是词汇范围。