在Javascript中,为什么“this”运算符不一致?

2023-12-22

在 JavaScript 中,“this”运算符在不同场景下可以指代不同的事物。

通常,在 JavaScript“对象”内的方法中,它指的是当前对象。

但当用作回调时,它变成对调用对象的引用。

我发现这会导致代码出现问题,因为如果您使用 JavaScript“对象”中的方法作为回调函数,您无法判断“this”是否引用当前“对象”或“this”是否引用调用对象。

有人可以澄清有关如何解决此问题的用法和最佳实践吗?

   function TestObject() {
            TestObject.prototype.firstMethod = function(){
                      this.callback();
                      YAHOO.util.Connect.asyncRequest(method, uri, callBack);

            }

            TestObject.prototype.callBack = function(o){
              // do something with "this"
              //when method is called directly, "this" resolves to the current object
              //when invoked by the asyncRequest callback, "this" is not the current object
              //what design patterns can make this consistent?
              this.secondMethod();
            }
            TestObject.prototype.secondMethod = function() {
             alert('test');
            }
        }

在我喋喋不休地谈论魔法之前,快速提供有关最佳实践的建议this多变的。如果您希望 Javascript 中的面向对象编程 (OOP) 能够密切反映更传统/经典的继承模式,请选择一个框架,了解其怪癖,并且不要试图变得聪明。如果你想变得聪明,就将 javascript 作为一种函数式语言来学习,并避免考虑类之类的事情。

这提出了关于 Javascript 需要牢记的最重要的事情之一,并在没有意义时对自己重复一遍。 JavaScript 没有类。如果某个东西看起来像一个类,那么这是一个聪明的技巧。 JavaScript 有objects(不需要嘲笑的引用)和功能。 (这不是 100% 准确,函数只是对象,但有时将它们视为单独的事物会有所帮助)

The this变量附加到函数上。每当你调用一个函数时,this被赋予一定的值,具体取决于您调用该函数的方式。这通常称为调用模式。

JavaScript 中有四种调用函数的方法。您可以将该函数作为method, as a function, as a 构造函数, 与apply.

作为一种方法

方法是附加到对象的函数

var foo = {};
foo.someMethod = function(){
    alert(this);
}

当作为方法调用时,this将绑定到函数/方法所属的对象。在此示例中,这将绑定到 foo。

作为函数

如果您有独立的功能,this变量将绑定到“全局”对象,几乎总是window浏览器上下文中的对象。

 var foo = function(){
    alert(this);
 }
 foo();

这可能就是让你绊倒的原因,但不要感觉不好。许多人认为这是一个糟糕的设计决策。由于回调是作为函数而不是方法调用的,因此您会看到看似不一致的行为。

许多人通过做类似的事情来解决这个问题

var foo = {};
foo.someMethod = function (){
    var that=this;
    function bar(){
        alert(that);
    }
}

你定义一个变量that这指向this。关闭(它自己的主题)保留that周围,​​所以如果你调用 bar 作为回调,它仍然有一个引用。

作为建造者

您还可以调用函数作为构造函数。根据您使用的命名约定(TestObject) 这也是可能是你正在做的事情并且是让你绊倒的原因.

您可以使用以下命令将函数作为构造函数调用new关键词。

function Foo(){
    this.confusing = 'hell yeah';
}
var myObject = new Foo();

当作为构造函数调用时,将创建一个新对象,并且this将绑定到该对象。同样,如果您有内部函数并且它们被用作回调,您将把它们作为函数调用,并且this将绑定到全局对象。用那个var that = this;技巧/模式。

有些人认为 constructor/new 关键字是扔给 Java/传统 OOP 程序员的一块骨头,作为创建类似于类的东西的一种方式。

使用应用方法。

最后,每个函数都有一个名为的方法(是的,函数是 Javascript 中的对象)apply。应用可以让您确定什么值this将会是,并且还允许您传递一个参数数组。这是一个无用的例子。

function foo(a,b){
    alert(a);
    alert(b);
    alert(this);
}
var args = ['ah','be'];
foo.apply('omg',args);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Javascript中,为什么“this”运算符不一致? 的相关文章

  • 在 Three.js 中绕点旋转对象的正确方法是什么?

    关于 Three js 的大多数教程 问题都建议使用 Three js 绕点旋转对象的方法是在要旋转的位置创建父对象 附加对象 然后移动子对象 然后 当父级旋转时 子级围绕该点旋转 例如 Make a pivot var pivot new
  • 将 Javascript 对象的属性从 string 更改为 int

    我有一个对象数组 每个对象具有三个属性 年份 总计 人均 例子 0 Object per capita 125 8 total 1007 2 year 2009 这些属性是字符串 我想创建一个循环来遍历数组并将它们转换为 int 我尝试了以
  • 在 HTML5 Javascript 中将 BlobBuilder 转换为字符串

    function blobToString blob var reader new FileReader var d reader onloadend function d callback reader result console lo
  • 显示具有多个父代的 D3 树

    我目前有this http bl ocks org mbostock 4339083图已实现 我希望在描述具有多个父节点的子节点时保持结构和可折叠性 有没有办法做到这一点 我研究了力图 但我也想保留一组层次结构 这意味着 1 级的父级可以有
  • Firebase,只得到新的孩子[重复]

    这个问题在这里已经有答案了 var firebase new Firebase firebaseRef on child added function snapshot 这将接收所有元素 有没有办法在创建新的 Firebase 引用时不接收
  • 在 Internet Explorer 中使用什么来监视 jscript 内存使用情况

    我们正在调试 GWT 应用程序 在 Firefox 中运行正常 在 IE6 0 中开始运行正常 但一段时间后 它就会崩溃并开始爬行 经过一些测试后 我们怀疑存在一些内存问题 使用了太多内存 内存泄漏等 除了使用taskmanager和pro
  • 如何在没有 jQuery 的情况下删除 Javascript 中的元素

    我试图通过以下方式从 DOM 中删除 Div a 标签嵌套在其中 我想我正在寻找的是 jQuery 的纯 Javascript 版本 div remove 这是html设置 div a href Click me to remove the
  • Number.IsNaN() 比 isNaN() 更糟糕吗

    Soooooo isNaNJavaScript 显然被破坏了 比如 isNaN isNaN isNaN true isNaN false isNaN 0 返回 false 当它们看起来都是 不是数字 在 ECMAScript 6 中 草案包
  • 导航栏下拉菜单(折叠)在 Bootstrap 5 中不起作用

    我在尝试使用以下命令创建响应式菜单或下拉按钮时遇到问题Bootstrap 5一切似乎都正常 导航图标和下拉图标出现 但它不起作用 当我单击nav图标或dropdown按钮 无dropdown menu apears 我想特别提到的是 我还包
  • javascript 选择自定义光标 (svg)

    我正在动态地将光标更改为悬停时的本地 svg element on mouseover function this css cursor url svgs pointer svg 9 30 auto 工作正常 但我想选择该 svg 来操纵其
  • 如何通过单击链接来更改 div 的内容?

    这是我的网页的 修改后的 jsfiddle 它还有很多 而且定位是正确的 与此相反 http jsfiddle net ry0tec3p 1 http jsfiddle net ry0tec3p 1 a href class btn1 st
  • JavaScript 中的 Promise 有什么意义?

    一个承诺是一个 可能现在可用 或将来可用 或永远不可用的值 来源 MDN 假设我有一个想要处理图片的应用程序 图片已加载 例如在算法在后台使用它之后 或某种其他类型的延迟 现在我想检查一下图片是否可以在future 通过使用承诺 而不是回调
  • 如何始终将焦点保持在文本框中

    我创建了一个包含两个 div 的 HTML 页面 左侧的 div 页面的 90 是 ajax 结果的目标 右侧的 div 页面的 10 包含一个文本框 该页面的想法是在文本框中输入零件编号 通过条形码扫描仪 并显示与该零件编号匹配的绘图 显
  • 使用 Google 日历源时如何禁用 FullCalendar 中的活动链接?

    我正在使用 FullCalendar 库从 Google 日历加载日历中的事件 不幸的是 事件添加到日历后 它们是可点击的 当您点击该活动时 您会自动重定向到 Google 日历页面以查看该特定活动 或者如果您有足够的访问权限 则可以直接对
  • JavaScript eval("{}") 返回行为?

    根据ECMA 262 规范 http www ecma international org publications files ECMA ST Ecma 262 pdf 以下语句返回1 eval 1 eval 1 eval 1 var a
  • 使用 Jade 评估自定义 javascript 方法 (CircularJSON)

    我想通过 Jade 将一个对象解析为客户端 JavaScript 通常这会起作用 script var object JSON parse JSON stringify object but my object is circular ht
  • react-native - 图像需要来自 JSON 的本地路径

    你好社区 我正在react native中开发一个测试应用程序 并尝试从本地存储位置获取图像 我实际在做什么 我将图像直接链接源提供给 var 并在渲染函数中调用此方法 react 0 14 8 react native 0 23 1 np
  • 将数组从 jquery ajax 传递到代码后面

    我必须将二维数组传递给在asp net网页代码后面编写的页面方法我有一个变量objList作为二维数组 我使用以下代码来实现此目的 但没有成功 并且未调用页面方法 脚本语言 function BindTable objList ajax u
  • 仅当显式选择行时才关闭 ui-bootstrap typeahead

    我创建了这个jsBin http jsbin com livuqafe 2 edit来证明我遇到的问题 如果您转到此处 请尝试输入 五 并继续 你的自然反应是输入 五 然后按 Tab 如果你想要 五百 你可以向下箭头一次 但是 在这种情况下
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo

随机推荐

  • 如何在 macbook pro 中运行 docker 时启用虚拟化功能

    I want to run docker in my macbook pro but an error come to my eyes Firstly I think my cpu don t have the virtualization
  • 继承还是组合:依赖“is-a”和“has-a”?

    当我设计类并且必须在继承和组合之间进行选择时 我通常使用经验法则 如果关系是 is a 使用继承 如果关系是 has a 使用组合 总是对的吗 谢谢 不 是 并不总是导致继承 一个经常被引用的例子是正方形和长方形之间的关系 正方形是矩形 但
  • 计算内部有循环的递归函数的时间复杂度

    我正在研究一个简单的问题 我想出了一个 C 递归函数 下面是我的函数 void test int arr int n int x 0 cout lt
  • 圆角的QDialog有黑角而不是半透明

    我需要创建一个QDialog https doc qt io qt 5 qdialog html带有半透明的圆角 问题是这样做时 角是半透明的 但以某种方式被窗口的 alpha 属性填充 使其变黑 这是我对问题原因的理解 清晰可见的是圆形边
  • belongs_to 关联上的 :conditions 的目的是什么?

    假设我与附加条件有以下关联 belongs to admin user class name gt User foreign key gt admin user id conditions gt users admin TRUE or an
  • javascript element.scrollLeft 不工作

    我正在尝试使用滑块 我希望能够滚动到滑块的特定位置 从 MDN 文档看来 我可以使用 element scrollLeft 滚动到特定位置 虽然我似乎不为我工作 var container document getElementById c
  • Oracle 11G 中的限制/偏移

    我正在尝试更新 Oracle 中的表 但遇到了一些困难 我正在从 MySQL 移植代码 但 Oracle 不支持 MySQL 允许的一些命令 这是 MySQL 代码 update table1 t1 set c5 select Contra
  • 在同一文件中找不到类[重复]

    这个问题在这里已经有答案了 可能的重复 稍后在同一文件中定义的派生类 不存在 https stackoverflow com questions 12617188 derived class defined later in the sam
  • 是否有一个Matlab条件IF运算符可以像VBA的IIF一样放置在INLINE中

    在 VBA 中我可以执行以下操作 A B IIF C gt 0 C 0 所以如果 C gt 0 我得到A B C和 CA B 是否有一个运算符或函数可以让我执行这些条件inline在 MATLAB 代码中 简单地利用 MATLAB 在操作需
  • 使用 Twisted Python 的 SMTP 模块清理资源

    这与之前回答的问题有关 使用 Twisted 记录 SMTP 连接 https stackoverflow com questions 12164557 logging smtp connections with twisted 我有一个在
  • 调用“pip install”时运行自定义任务

    我想让我的 python 包 pip installable 问题是该包具有必须源自用户的 init shell 脚本的 shell 脚本 例如 bashrc 但安装后 用户并不确切知道脚本去了哪里 大概是 usr bin 但我们不能保证
  • rubyracer 或 libv8 在 Rails 应用程序中的用途是什么?

    我当时正在做一个项目 经常遇到 therubyracer 和 libv8 的问题 所以我决定删除它们 似乎唯一使用它们作为依赖项的是 less rails 无论如何我都想删除它 我的主要问题是它们的用途是什么 我在普通应用程序中是否需要它们
  • 拆分 BigIntegers 数字

    我正在尝试分割一个大整数的数字 让我说得更具体一些 我正在使用斐波那契序列生成一个大整数 现在使用这个算法我需要循环 直到找到一个 BigInteger 其中前 9 位数字和最后 9 位数字是泛数字 唯一的问题是我必须循环的数量是 300K
  • 对从 Ansible Tower (awx) 执行的 fetch_module 进行故障排除

    我正在尝试从远程主机执行一个非常简单的获取文件 不知怎的 我从来没有让它发挥作用 从远程 Linux 机器获取到 Ansible Tower awx 主机 也是 Linux 机器 这是 Ansible 代码 name get new pri
  • 活动 onCreate 中的 java.util.ConcurrentModificationException

    在最近的一个版本中 我通过 Admob 广告中介添加了 MoPub 我在崩溃日志中看到了一堆 ConcurrentModificationException 这一切似乎都是本机代码 我使用的是所有广告相关和 google android 相
  • Android FragmentTab 宿主和 Fragments 内的 Fragments

    我有一个具有如下层次结构的应用程序 FragmentTabHost Main Activity Fragment tab 1 content splitter view Fragment lhs list Framment rhs cont
  • PHP - fopen($url) 无法打开流:权限被拒绝

    我的网站必须具有非常相似的 php 配置 实际上在同一个托管帐户上 具有几乎相同的 php 代码和相同的文件结构 在某个时刻 我打电话fopen http example com rssfedd xml 检索 RSS 提要 on http
  • 具有多个 X 轴列的 ASP 图表

    我有一个包含两列的 SQL 表 销售人员和状态 状态可以是金 银 铜三种状态之一 如何创建一个图表 其中销售人员姓名沿 x 轴出现一次 但其姓名上方有三列用于显示每种状态的计数 谢谢 乔诺 如果我理解正确的话 你正在尝试做类似这篇文章的事情
  • 在QTabBar中隐藏底线

    似乎没有办法为底线 如下图所示 设置样式表QTabBar 我想将其删除 我怎样才能删除它 现在已经 6 7 个月没有使用 Qt 了 所以我不确定这是否有效 也无法测试它 给QTabBar drawBase http qt project o
  • 在Javascript中,为什么“this”运算符不一致?

    在 JavaScript 中 this 运算符在不同场景下可以指代不同的事物 通常 在 JavaScript 对象 内的方法中 它指的是当前对象 但当用作回调时 它变成对调用对象的引用 我发现这会导致代码出现问题 因为如果您使用 JavaS