Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript `var self=this`是否被视为代码气味?_Javascript - Fatal编程技术网

Javascript `var self=this`是否被视为代码气味?

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

目前正在pluralsight上观看“高级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);
};
他说,它修复了
这个问题,但导致了另一个问题。上面使用了一个命名函数,因此可以解除绑定。但他表示,函数的名称并不是现在定义的名称。被绑定的函数是新的硬绑定函数,因此它不能被解除绑定,因为我们没有硬绑定函数的引用。嗯?谁能解释一下。他没有详细说明

紧接着,他解释了解决问题的最佳方法是使用自我参考:

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具有功能范围,而不是词汇范围。