在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”运算符不一致? 的相关文章

  • 为任何更新查询增加 Mongoose 文档版本的简单方法?

    我想开始利用 Mongooses 文档版本控制 v key 我在实际增加版本值时遇到了问题 然后我发现您必须添加this increment 执行查询时 有没有办法自动递增 目前 我只是将其添加到pre用于更新类型查询的中间件 module
  • AJAX 安全问题

    我希望能够解决一些关于 AJAX 安全性的问题 这是我试图理解的一个场景 假设我正在使用 AJAX 向页面请求一些半敏感材料 例如 我将把用户的 ID 传递给一个 php 文件 并返回一些关于他们自己的信息 现在 是什么阻止人们模拟此 Ja
  • 检测单选按钮/复选框状态的变化

    我需要可靠地检测页面上单选按钮 复选框的状态变化 以便查看表单是否被修改 现在 这是一个完全独立的脚本 我无法修改任何控制表单的内容 目前 我只能看到两种方法 onchange事件处理程序 有助于处理文本框 文本区域和选择 但不会针对复选框
  • 如何恢复文本框数据

    我有一个小小的要求 我们已经恢复了之前清除的文本框数据 下面是我的 HTML 代码 table tr td td tr table
  • 当内部元素滚动位置到达顶部/底部时防止父元素滚动?

    我有一个小 浮动工具箱 一个带有position fixed overflow auto 效果很好 但是 当在该框内滚动 使用鼠标滚轮 并到达底部或顶部时 父元素 接管 滚动请求 工具框后面的文档滚动 这很烦人 而不是用户 要求的 我正在使
  • 我可以通过什么方式混合 jQuery 和 vanilla JavaScript

    我有一个用普通 JavaScript 编写的 Web 应用程序 我想用 jQuery 动画来增强它 并使用我在各种 jQuery 插件中找到的一些功能 例如上传 http www uploadify com 可以通过什么方式将 jQuery
  • 如何使用多个 select2 框过滤表格?

    我正在尝试使用 和多个 select2 框的类来过滤表格 表格 HTML table class table tbody tr class kanban event Austin td td tr tr class csm event Ch
  • 如何将 Ajax.BeginForm MVC 助手与 JSON 结果一起使用?

    我正在尝试使用 ASP NET MVC Ajax BeginForm 帮助程序 但不想在调用完成时使用现有的内容插入选项 相反 我想使用自定义 JavaScript 函数作为回调 这可行 但我想要的结果应该以 JSON 形式返回 不幸的是
  • Javascript 作为对象键的函数与块中标记函数之间的语法冲突

    假设您有一个支持两者的浏览器带标签的函数声明 https developer mozilla org en US docs Web JavaScript Reference Statements label Labeled function
  • 如何显示接下来的三个图像单击加载更多按钮

    我需要一个加载更多按钮来显示图像 页面加载时 我显示 3 个图像 单击 加载更多 按钮后 接下来的 3 个图像将显示在屏幕上 我尝试了下面的代码 但它不起作用 你能帮我解决这个问题吗 function item slice 0 2 show
  • Chrome --app 相当于 Firefox\IE

    我有一个网络应用程序 客户要求单击不同按钮时更改浏览器窗口大小 我发现在那link https stackoverflow com questions 13436855 launch google chrome from the comma
  • 如何知道 .keyup() 是否是字符键(jQuery)

    如何知道 keyup 是否是字符键 jQuery input keyup function if key is a character such as a b A b c 5 3 2 etc not enter key or shift o
  • 从字节数组设置 img src

    我需要设置img src我在对象中拥有的字节数组的属性 img
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 在反应中访问回调内的 event.target

    我有以下课程片段 constructor props super props this timeout null search e gt clearTimeout this timeout this timeout setTimeout f
  • 如何将MathJax公式转换为img

    Mathjax 现在在我的项目中运行良好 但有一个问题 有没有办法将MathJax的公式 纯html和css 转换成img文件 我可以保存 MathJax 可以配置为生成 SVG 看http docs mathjax org en late
  • Google 地图 API - 地图未显示 - 没有错误

    我正在尝试将地图从 Google API 加载到 div 中 但是 地图未加载 并且没有输出任何错误 这是代码 google maps var geocoder map function codeAddress address geocod
  • 如何在 TypeScript 中使用 navigation.replace ?

    我试图在我的代码中使用它 const navigation useNavigation navigation replace AllFriends 但我不断收到错误消息 Property replace does not exist on
  • Graphql 将多个查询合并(组合)为一个?

    我正在尝试使用 JavaScript 将多个 GraphQL 查询合并为一个查询 我正在寻找这样的东西 let query3 mergeQueries query1 query2 我们事先不知道哪些查询将被组合 假设我有这样的查询 输入查询
  • Vue - 调度完成后调用 store getter?

    我正在使用 Laravel 5 7 Vue2 Vuex 我在调度调用完成后让 Vue 返回存储值时遇到一些困难 我的申请流程如下 我单击一个提交按钮 该按钮调用组件上的 validate Validate 分派到我的 addLease 操作

随机推荐

  • 如何在 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