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

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

问题描述

我刚开始使用原型JavaScript,而我在查找如何在原型函数内部保留对主对象的引用时遇到问题范围变化。让我说明一下我的意思(我在这里使用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();

我知道我可以在<$开头执行此操作来保留对主对象的引用c $ c> myfunc :

var myThis = this;

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

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; 因为即使在 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的一部分版本规范,此功能的实现很简单(只有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 + '\n' + 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 value),定义为 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()),就像一个简单的函数调用一样,在这种类型的调用中,这个关键字里面会引用Global对象,它会提醒全局测试。

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".

现在, fx2 是生成 bind 方法的新函数,它将调用我们的函数保留上下文并正确传递参数,它将警告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天全站免登陆