当前位置: 首页 > 面试题库 >

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

甄霖
2023-03-14
问题内容

我刚刚开始使用原型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();

在那种情况下,我无法创建对主对象的引用,varmyThis=this;因为即使this上下文中的原始值doSomething也是一个jQuery对象,而不是一个MyClass对象。

有人建议我使用全局变量来保存对原始文件的引用this,但这对我来说似乎是个坏主意。我不想污染全局名称空间,这似乎会使我无法实例化两个不同的MyClass对象而又不会相互干扰。

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


问题答案:

为了保留上下文,该bind方法非常有用,它是最近发布的ECMAScript5thEdition规范的一部分,此函数的实现很简单(只有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内部关键字将引用全局对象,它将警告“全局测试”。

现在,方法fx2是该bind方法生成的新函数,它将调用我们的函数以保留上下文并正确传递参数,它将警告“ obj test
1,2,3,4,5”,因为我们调用了该函数将其添加了两个论据,它已经 绑定 了前三个。



 类似资料:
  • 问题内容: 我发现自己将“ this”分配给变量,因此可以轻松地在回调和闭包中使用它。 这是不好的做法吗?有没有更好的方法可以参考原始功能? 这是一个典型的例子。 您通常使用这种方法还是找到了更清洁的解决方案? 问题答案: 处理回调的主要方法有三种: 1.按照当前操作,创建一个词法范围的变量 此新变量的两个最常见的名称是和。我个人更喜欢使用,因为浏览器具有一个名为self的全局窗口属性,而我的li

  • 问题内容: 我已经使用JavaScript原型和继承构建了一个大型应用程序。但是我很难组织我的代码。例如,我有一个类轮播,它具有许多类似这样的功能: 我想这样组织我的代码: 但是,这将导致“ this”的值丢失。我可以使用全局实例来跟踪它,但是当类被继承时这会引起问题,例如,在另一个文件中,我有类似的东西可以覆盖父类。 我的继承是这样完成的: 所以我可以做: 有谁知道我该如何处理“ this”值?

  • 问题内容: 我从javascript对象内部进行了一些Ajax调用。 在onreadystatechange函数内部,它不再引用主对象,因此我无法访问this.foo。我如何在XMLHttpRequest事件中保留对主对象的引用? 问题答案: 最简单的方法通常是将的值存储在局部变量中: 我也怀疑您的标识符确实是构造函数(您正在分配属性)。 如果是这种情况,请不要忘记添加正确的属性(因为您正在替换整

  • 问题内容: 通常,在setInterval中引用“ this”时,我会分配一个替代的“ self”引用。是否可以在原型方法的上下文中完成类似的任务?以下代码错误。 问题答案: 与Python之类的语言不同,Javascript方法忘记了将其提取并传递到其他地方后才使用的方法。你可以 将方法调用包装在匿名函数中 这样,访问属性并调用它是同时发生的,这是在方法调用中正确设置的必要条件。 您将需要将外部

  • 问题内容: 我有一个要覆盖的函数,但也有一个要根据上下文按顺序执行的功能。例如,有时在生成页面时,我会想要像这样覆盖: 有时像这样: 我如何从最重要的方面得到它?可能吗 我知道很多人都建议不要以这种方式替代替代。我在问这种方式。 问题答案: 您可以执行以下操作: 在匿名函数内部进行声明可以防止其混乱全局名称空间,但可以在内部函数中使用它。 就像评论中提到的Nerdmaster一样,一定要在最后加上

  • 问题内容: 我正在制作一个bash脚本,该脚本将打印并将复杂的参数传递给另一个外部程序。 我该如何打印原始参数: 使用并删除可能引起不良结果的单引号。我的脚本不需要解析每个参数。我只需要打印/记录参数字符串,然后将其确切地传递给另一个程序。 我知道我可以使用类似的东西来避免引号, 但是我不能保证用户会这样做。 问题答案: 在将参数传递到脚本之前,引号已被删除,因此保留它们为时已晚。您可以做的是在将