在JavaScript原型函数中保留对“此”的引用

在JavaScript原型函数中保留对“此”的引用

我只是开始使用原型JavaScript,我很难找到如何保存this当作用域改变时,从原型函数中引用主对象。让我来解释一下我的意思(我在这里使用jQuery):

MyClass = function() {
  this.element = $('#element');
  this.myValue = 'something';

  // some more code}MyClass.prototype.myfunc = function() {
  // at this point, "this" refers to the instance of MyClass

  this.element.click(function() {
    // at this point, "this" refers to the DOM element
    // but what if I want to access the original "this.myValue"?
  });}new MyClass();

我知道,我可以保留对主对象的引用,方法是在myfunc:

var myThis = this;

然后使用myThis.myValue若要访问主对象的属性,请执行以下操作。但是当我有大量的原型函数时会发生什么?MyClass?我是否必须保存引用this在每一个开始的时候?看来应该有个更干净的方法。那么像这样的情况呢:

MyClass = function() {
  this.elements $('.elements');
  this.myValue = 'something';

  this.elements.each(this.doSomething);}MyClass.prototype.doSomething = function() {
  // operate on the element}new MyClass();

在这种情况下,我无法创建对主对象的引用var myThis = this;因为即使是this在.的范围内doSomethingjQuery对象,而不是MyClass对象。

有人建议我使用一个全局变量来保存对原始this但对我来说这似乎是个坏主意。我不想污染全局名称空间,这似乎会阻止我实例化两个不同的名称空间。MyClass没有互相干扰的物体。

有什么建议吗?有干净的方法做我想要做的事吗?还是我的整个设计模式都有缺陷?


哔哔one
浏览 235回答 3
3回答

饮歌长啸

为你的最后一次MyClass例如,您可以这样做:var myThis=this;this.elements.each(function() { myThis.doSomething.apply(myThis, arguments); });在传递给each, this引用jQuery对象,您已经知道了。如果在该函数中,您将获得doSomething功能来自myThis,然后使用参数数组调用该函数的Apply方法(请参阅apply功能而arguments变量),那么this将被设置为myThis在……里面doSomething.

慕莱坞森

我意识到这是一个旧的线程,但我有一个更优雅的解决方案,除了我已经注意到的一般情况之外,它几乎没有什么缺点。考虑以下几点:var f=function(){     var context=this;}    f.prototype.test=function(){     return context;}    var fn=new f();fn.test(); // should return undefined because the prototype definition     // took place outside the scope where 'context' is available在上面的函数中,我们定义了一个局部变量(上下文)。然后,我们添加了一个返回局部变量的原型函数(Test)。正如您可能已经预测的,当我们创建这个函数的一个实例,然后执行测试方法时,它不会返回局部变量,因为当我们将原型函数定义为我们的主函数的成员时,它超出了定义局部变量的范围。这是一个常见的问题,需要创建函数,然后向其添加原型-您不能访问在主函数范围内创建的任何内容。要创建局部变量范围内的方法,我们需要直接将它们定义为函数的成员,并去掉原型引用:var f=function(){     var context=this;         this.test=function(){         console.log(context);         return context;     };}    var fn=new(f);fn.test(); //should return an object that correctly references 'this'//in the context of that function;         fn.test().test().test(); //proving that 'this' is the correct reference;您可能担心,由于这些方法不是原型创建的,因此不同的实例可能并不真正是数据分离的。为了证明它们是这样的,请考虑以下几点:var f=function(val){     var self=this;     this.chain=function(){         return self;     };         this.checkval=function(){         return val;     };}    var fn1=new f('first value');var fn2=new f('second value');    fn1.checkval();fn1.chain().chain().checkval();     // returns 'first value' indicating that not only does the initiated value remain untouched,     // one can use the internally stored context reference rigorously without losing sight of local variables.          fn2.checkval();fn2.chain().chain().checkval();// the fact that this set of tests returns 'second value'     // proves that they are really referencing separate instances使用此方法的另一种方法是创建单例。通常情况下,我们的javascript函数不会被实例化不止一次。如果您知道您永远不需要同一个函数的第二个实例,那么就有一种简单的方法来创建它们。不过,请注意:lint会抱怨这是一个奇怪的结构,并质疑您使用关键字“new”:fn=new function(val){     var self=this;     this.chain=function(){         return self;     };             this.checkval=function(){         return val;     };  }    fn.checkval();fn.chain().chain().checkval();专业人士:使用此方法创建函数对象的好处很多。它使您的代码更易于阅读,因为它缩进函数对象的方法,使其直观地更易于理解。它允许访问本地定义的变量。仅在最初以这种方式定义的方法中即使稍后向函数对象添加原型函数或成员函数,它也不能访问局部变量,而且您在该级别上存储的任何功能或数据在其他任何地方都是安全和不可访问的。它允许一种简单而直截了当的方式来定义单子。它允许您存储对“this”的引用,并无限期地维护该引用。康:使用这种方法有一些缺点。我不假装是全面的:)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript