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

2024-01-01

我刚刚开始使用原型 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在上下文中doSomething is a jQuery对象而不是一个MyClass object.

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

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


为了保留上下文,bind方法确实有用,它现在是最近发布的一部分ECMAScript 第五版 http://www.ecma-international.org/publications/standards/Ecma-262.htm规范来说,这个函数的实现很简单(只有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”。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 JavaScript 原型函数中保留对“this”的引用[重复] 的相关文章

随机推荐

  • 在 SICP 中推广素数对

    我花了一些时间来研究 素数对 的生成SICP 第 2 2 3 节 作为常规接口的序列 例如 1 3 不 因为总和 4 1 4 是的 因为 sum 5 素数 这是我从头开始得到的 有效的 lang sicp RANGE helper func
  • Android DatePicker 在使用最小/最大限制时显示不可用月份

    我在 StackOverflow 上只发现了这个问题的另外 1 个实例 但尚未得到答复 去年 所以我想我应该再试一次 Android DatePicker Dialog 使用最小 最大日期显示不正确的月份 秒 https stackover
  • 在 React 中使用 requestAnimationFrame

    我是原生反应新手 我正在尝试优化性能 我的触摸事件非常慢 我正在经历RN 性能文档 https facebook github io react native docs performance my touchablex view isn
  • 如何在rails3中使用amistad gem?

    我需要有关如何在 Rails3 应用程序中实现 AMISTAD gem 的帮助 请建议一些教程或观点 我看到了 github amistad 链接 但我想要对这颗宝石进行全面报道 请帮我 gem 创建者请给我发送一个如何使用 GEM 的示例
  • 是否可以在 android 中使用 Actionbar sherlock 在操作菜单项中实现切换按钮

    我有一个应用程序 它在操作菜单项中有切换按钮 尽管我使用的是 Actionbar Sherlock 但我不知道如何将切换按钮放置在操作菜单项中 我不想将其作为自定义布局放置在操作栏中 但我想将其放置为菜单项 如果有人找到解决方案 请帮助我
  • Google Analytics(分析)不会跟踪 iOS 上的视图?

    我已将最新的 Google Analytics SDK 添加到我的 iOS 应用程序中 版本 2 0 beta 4 我按照指南所述进行了相同的操作 并将以下代码添加到应用程序委托中 Optional automatically send u
  • 如何从现有的 github 项目添加 helm 存储库?

    我有一个现有的 github 项目 我想创建 添加一个helm文件夹到项目中以存储 helm yaml 文件 我想引用这个 github 项目 文件夹来充当我的本地 开发环境中的 helm 存储库 我知道我可以将图表添加到我的本地 默认 h
  • 为Unity构建一个简单的在线游戏服务器

    我正在尝试为我的坦克游戏 2D Unity 构建一个在线游戏服务器 在我的游戏中会有2 4名玩家控制他们的坦克并互相战斗 我尝试过使用 Unity 网络 它不太适合我的游戏 因为我们必须选择房间中的 1 名玩家作为 服务器 这对于我未来的开
  • 固定分配 std::vector

    我是一名嵌入式软件开发人员 因此我不能总是使用所有优秀的 C 功能 最困难的事情之一是避免动态内存分配 因为它对于所有 STL 容器来说都是通用的 The std vector然而 在处理可变数据集时非常有用 但问题是分配 例如std re
  • 将命令行参数传递给 Clozure common lisp

    我之前熟悉python 现在我正在尝试学习common lisp并在windows系统下使用ccl clozure common lisp 我发现没有一种方便的方法来将 lisp 文件作为 python 运行 所以我写了一个bat文件来编译
  • 无法访问映射到 docker 容器端口的主机上的端口

    我已经使用命令启动了一个 docker 容器 sudo docker run it P d plcdimage 该映像是使用具有 EXPOSE 8080 指令的 Dockerfile 构建的 容器运行 jboss 服务器 并在其上部署了应用
  • 如何从函数(UDF)返回表变量?

    我正在使用 SQL Server 2012 并且一直在尝试许多不同的方法来从函数内部返回表变量 但我无法让它工作 我尝试过将变量声明移动到不同的位置等 这是 sql 的核心内容 如果您可以将内容包装在一个 UDF 函数中 该函数实际编译并返
  • 在 Android 上以编程方式发送彩信

    我在执行一项任务时遇到了问题 我应该在 android 2 1 上使用我们自己的界面发送彩信 所以你可以猜测调用默认的 Activity 是不可能的 所以我的问题是 有没有一种方法可以使用 android SDK 以编程方式发送彩信 没有说
  • 如何将 Twitter 小部件插入 GWT 视图

    我有一个在 GWT 应用程序中创建的视图 我想嵌入 使用 twitter 提供的 Twitter 小部件之一 就像这个 http twitter com about resources widgets widget search http
  • 向脚本添加密码屏蔽

    为了练习 我正在编写一个程序来隐藏文件夹 程序本身运行良好 但我想用星号 屏蔽我的输入 我找到了将输入屏蔽为独立脚本的代码 但我无法找到将代码集成到我的代码中的方法 任何帮助将不胜感激 程序代码 echo off color 5F titl
  • 核心数据 - 放弃更改

    希望有人能解释一下发生了什么事 如果我从核心数据模型中获取一个对象 请修改模型中未保留甚至未定义的属性 然后销毁并再次获取该对象 该值仍为先前设置的值 为什么是这样 Promotion promotion Promotion promoti
  • 更改 user.home 系统属性

    如何从 java 程序外部更改 user home 系统属性 以便它认为它是与 D Documents and Settings USERNAME 不同的目录 通过环境变量还是虚拟机参数 设置 VM 参数应该有效 java Duser ho
  • 使用 xlrd 从 Python 中的 Excel 工作表超链接获取 URL

    我正在尝试使用 xlrd 获取 Excel 工作表第二列中元素的超链接 URL 使用时 book open workbook mypath formatting info True sheet book sheet by index 0 r
  • 了解两个不同大小矩阵的 np.corrcoef 输出

    我想计算每个之间的相关性列向量矩阵的A与每个列向量矩阵的B 考虑 vectorsize 777 A np random rand vectorsize 64 B np random rand vectorsize 36 corr np co
  • 在 JavaScript 原型函数中保留对“this”的引用[重复]

    这个问题在这里已经有答案了 我刚刚开始使用原型 JavaScript 但在弄清楚如何保存this当作用域发生变化时 从原型函数内部引用主对象 让我解释一下我的意思 我在这里使用 jQuery MyClass function this el