var self = this; 糟糕的模式?

Eve*_*ert 76 javascript

我发现自己需要:

var self = this;
Run Code Online (Sandbox Code Playgroud)

在我的javascript'类'中有很多.尽管通常这样做,但感觉有点不对劲.我希望在这个问题中找到的是一个更好的方法来处理这个问题,或者说服一些东西来说服这个问题是非常好的.

这是保持正确绑定的标准方法吗?我应该在任何地方标准化使用'self',除非我明确需要'this'.

编辑:我确切地知道为什么我需要这个,我只是想知道它是否被认为有点邪恶,为什么.我知道在调用方法时还有'apply'内置的javascript函数来显式定义范围.好点吗?

小智 48

正如其他人所说:这个"额外变量"是(在某种程度上)获得this特殊表达式这一事实的唯一方法,因此,不是变量,不会被绑定在执行上下文/闭包中.

但是,我认为你在问什么(或者我真正想要回答的问题)是:

应该放在var self = this每个方法/构造函数的顶部吗?

摘要

虽然我尝试了一次,并且有同样的问题,但我不再使用这种方法.现在我保留构造,以便在需要访问闭包时.对我而言,它增加了一点"嘿,这就是我真正想要的!" 我的代码语义:

this -> thisself -> this (but really that) in a closure

问题单点:

......虽然这种做法很常见,但感觉有些不对劲.我希望在这个问题中找到的是一个更好的方法来处理这个问题,或者说服一些东西来说服这个问题是非常好的.

做对你感觉合适的事.不要害怕尝试一种方法并稍后切换回来(但请尽量在每个项目中保持一致:-)

这是保持正确绑定的标准方法吗?我应该在任何地方标准化使用'self',除非我明确需要'this'.

"self"是最常用的名称.如上所述,我更喜欢相反的方法 - this除了需要闭包绑定时使用.

..如果它被认为有点邪恶,为什么.

邪恶是一个愚蠢的主观术语(虽然有时很有趣).我从来没有说过它是邪恶的,只是为什么我不遵循这个方法.有些人告诉我,因为不使用分号,我是"邪恶的".我告诉他们他们应该提出好的论据和/或更好地学习JavaScript :-)

我知道在调用方法时还有'apply'内置的javascript函数来显式定义范围.好点吗?

问题apply/call是您必须在函数调用时使用它们.如果其他打电话给你的一个方法,它this可能已经关闭,这将无济于事.它对于像jQuery样式的回调这样的东西最有用,其中回调this是元素/回调的项目等.

作为旁白...

喜欢避免成员上的"需要自我",因此通常会将所有成员函数提升到receiver(this)只是"流经"的属性,这通常是"按预期".

我的代码中的"私有"方法以"_"开头,如果用户调用它们,那就是它们.当使用原型方法创建对象时,这也可以更好地工作(非常需要).然而,道格拉斯·克罗克福德不同意我的这种"私人"方法,在某些情况下,查询链可能会通过注入一个意外的接收器来阻止你:

在构造函数中使用"self"绑定也会锁定方法的查找链的上限(它不再是多态的!),这可能是也可能不正确.我认为这通常是不正确的.

快乐的编码.

  • `aelf`是窗口对象 - 我会避免使用保留字,并使用`var that = this`或`var _self = this` (3认同)

Pet*_*ley 17

是的,这是标准方式.

Function.apply()并且Function.call()可以帮助,但并非总是如此.

考虑以下

function foo()
{
  var self = this;
  this.name = 'foo';

  setTimeout( function()
  {
    alert( "Hi from " + self.name );
  }, 1000 );       
}

new foo();
Run Code Online (Sandbox Code Playgroud)

如果你想这样做但是避免使用变量,比如self使用call()或者apply()代替......好吧......你看着它并开始尝试,但很快就意识到你不能.setTimeout()负责调用lambda,使您无法利用这些备用调用样式.您仍然最终会创建一些中间变量来保存对象的引用.

  • 对不起,如果我错过了,但如果你这样做就行了:`setTimeout((function(){alert("Hi from"+ this.name);}).apply(this),1000); }` (4认同)
  • @drodsou使用apply(this)将立即执行函数,从而返回undefined作为setTimeout的第一个参数,howether有一个绑定函数:window.setTimeout(function(){alert("Hi from"+ this.name);} .bind (this),1e3); (3认同)

bob*_*nce 9

这是保持正确绑定的标准方法吗?

没有标准,涉及JavaScript和类/实例系统.您将不得不选择您喜欢的对象模型.这是背景资料的另一个链接 ; 结论:没有结论.

通常var self= this;,在闭包中保留副本(*)与围绕闭包构建的对象模型一起使用每个方法的每个实例副本.这是一种有效的做事方式; 少了几分效率高,而且通常比其他工作少一点,对象模型构建围绕原型,使用this,apply()ECMAScript的第五版的,并bind()得到绑定方法.

什么可以被视为'邪恶'是当你在同一个代码中有两种风格的混合.不幸的是,许多常见的JS代码都是这样做的(因为让我们面对它,没有人真正理解JavaScript奇特的原生对象模型).

(*:我通常使用that而不是self;你可以使用你喜欢的任何变量名,但self作为window指向窗口本身的成员,已经有一些模糊和完全无意义的含义.)


Ale*_*erB 7

刚刚遇到这个问题,因为我的同事沉迷于自我/变量,我想了解为什么......

我认为现在有更好的方法可以解决这个问题:

function () {}.bind(this);      // native
_.bind(function () {}, this);   // lodash
$.proxy(function () {}, this);  // jquery
Run Code Online (Sandbox Code Playgroud)