保留对“this"的引用在 JavaScript 原型函数中 [英] Preserving a reference to "this" in JavaScript prototype functions

查看:32
本文介绍了保留对“this"的引用在 JavaScript 原型函数中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用原型 JavaScript,我无法弄清楚如何在范围更改时从原型函数内部保留对主对象的 this 引用.让我来说明我的意思(我在这里使用 jQuery):

I'm just getting into using prototypal JavaScript and I'm having trouble figuring out how to preserve a this reference to the main object from inside a prototype function when the scope changes. Let me illustrate what I mean (I'm using jQuery here):

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 的开头这样做来保留对主对象的引用:

I know that I can preserve a reference to the main object by doing this at the beginning of myfunc:

var myThis = this;

然后使用 myThis.myValue 访问主对象的属性.但是当我在 MyClass 上有一大堆原型函数时会发生什么?我是否必须在每个开头保存对 this 的引用?似乎应该有一种更清洁的方式.那么像这样的情况呢:

and then using myThis.myValue to access the main object's property. But what happens when I have a whole bunch of prototype functions on MyClass? Do I have to save the reference to this at the beginning of each one? Seems like there should be a cleaner way. And what about a situation like 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 的原始值在 <的上下文中code>doSomething 是一个 jQuery 对象而不是 MyClass 对象.

In that case, I can't create a reference to the main object with var myThis = this; because even the original value of this within the context of doSomething is a jQuery object and not a MyClass object.

有人建议我使用全局变量来保存对原始 this 的引用,但这对我来说似乎是一个非常糟糕的主意.我不想污染全局命名空间,这似乎会阻止我在不相互干扰的情况下实例化两个不同的 MyClass 对象.

It's been suggested to me to use a global variable to hold the reference to the original this, but that seems like a really bad idea to me. I don't want to pollute the global namespace and that seems like it would prevent me from instantiating two different MyClass objects without them interfering with each other.

有什么建议吗?有没有一种干净的方法来做我所追求的?还是我的整个设计模式有缺陷?

Any suggestions? Is there a clean way to do what I'm after? Or is my entire design pattern flawed?

推荐答案

为了保留上下文,bind 方法非常有用,它现在是最近发布的ECMAScript 5th Edition 规范,这个功能的实现很简单(只有8行):

For preserving the context, the bind method is really useful, it's now part of the recently released ECMAScript 5th Edition Specification, the implementation of this function is simple (only 8 lines long):

// The .bind method from Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

你可以使用它,在你的例子中是这样的:

And you could use it, in your example like this:

MyClass.prototype.myfunc = function() {

  this.element.click((function() {
    // ...
  }).bind(this));
};

另一个例子:

var obj = {
  test: 'obj test',
  fx: function() {
    alert(this.test + '
' + Array.prototype.slice.call(arguments).join());
  }
};

var test = "Global test";
var fx1 = obj.fx;
var fx2 = obj.fx.bind(obj, 1, 2, 3);

fx1(1,2);
fx2(4, 5);

在第二个例子中,我们可以观察到更多关于 bind 的行为.

In this second example we can observe more about the behavior of bind.

它基本上生成了一个新函数,它将负责调用我们的函数,保留函数上下文(this 值),它被定义为bind.

It basically generates a new function, that will be the responsible of calling our function, preserving the function context (this value), that is defined as the first argument of bind.

其余的参数只是简单地传递给我们的函数.

The rest of the arguments are simply passed to our function.

请注意,在此示例中,函数 fx1 是在没有任何对象上下文 (obj.method() ) 的情况下调用的,就像简单的函数调用,在这种类型的调用中,里面的this关键字会指向全局对象,会提示全局测试".

Note in this example that the function fx1, is invoked without any object context (obj.method() ), just as a simple function call, in this type of invokation, the this keyword inside will refer to the Global object, it will alert "global test".

现在,fx2bind 方法生成的新函数,它将调用我们的函数,保留上下文并正确传递参数,它会警告obj测试 1, 2, 3, 4, 5" 因为我们调用它并添加两个额外的参数,它已经绑定前三个.

Now, the fx2 is the new function that the bind method generated, it will call our function preserving the context and correctly passing the arguments, it will alert "obj test 1, 2, 3, 4, 5" because we invoked it adding the two additionally arguments, it already had binded the first three.

这篇关于保留对“this"的引用在 JavaScript 原型函数中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆