javascript - 在 JavaScript 原型(prototype)函数中保留对 "this"的引用

标签 javascript oop scope this prototype-programming

<分区>

我刚刚开始使用原型(prototype) JavaScript,但我无法弄清楚如何在作用域发生变化时从原型(prototype)函数内部保留对主对象的 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 上有一大堆原型(prototype)函数时会发生什么?我是否必须在每个代码的开头保存对 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 的原始值在 doSomething 是一个 jQuery 对象,而不是一个 MyClass 对象。

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

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

最佳答案

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

// 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))); 
    }; 
  };
}

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

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 的行为。

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

其余的参数只是传递给我们的函数。

请注意,在此示例中,调用函数 fx1 时没有任何对象上下文 (obj.method() ),就像简单的函数调用,在这种调用中,里面的this关键字会引用到Global对象,会提示“global test”。

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

关于javascript - 在 JavaScript 原型(prototype)函数中保留对 "this"的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2025789/

相关文章:

c++ - 如何返回在函数中创建的 char 数组?

javascript - 为什么Iife在一个简单的示例中不起作用?

javascript - 使用翻译的动画粘性标题

oop - 继承可以完全被组合取代吗?

java - Java中的接口(interface)是什么?

c++ - LPTSTR Losing Scope,变通无效 (C++)

javascript - 使用 JavaScript 单击时获取单选输入的值

javascript - CORS 策略阻止 localhost

c# - OOP中级教程

javascript - 将全局变量传递给 Javascript 中的事件回调函数?