在 forEach 中调用类函数:Javascript 如何处理“this”关键字

2024-04-16

我是 Javascript 新手,只是想确保我理解它如何处理this关键字,因为……嗯,看起来很混乱。我已经在 StackOverflow 上查看了类似的问题,并想确保我没有继续错误的想法。

所以我定义一个像这样的类,并且想要处理构造函数中收到的每个点。

function Curve(ptList) {
  this.pts = [];

  if(ptList.length > 2) {
    // I want to call "addPoint" for every item in ptList right here
  }
}

Curve.prototype.addPoint = function(p) { 
  this.pts.push(p);
  /* some more processing here */ 
}

所以,最初我想我可以这样做:

ptList.forEach(this.addPoint);

但我不能,因为这只是传递一个指向原型函数的指针,这意味着this in addPoint指的是全局对象。

然后我尝试:

ptList.forEach(function(p) { this.addPoint(p); });

但我不能,因为this一旦我进入该内部函数,就指的是全局范围(它不再指的是Curve正在构造的对象),所以addPoint未定义。

解决这个问题的方法是创建一个引用的变量this在我仍然可以在子功能中交谈的范围内:

var _this = this;
ptList.forEach(function(p) { _this.addPoint(p); });

这最终起作用了(但对于没有 JS 经验的人来说看起来真的很奇怪)。但后来我发现bind函数,这让我不能定义一个简单的函数包装器:

ptList.forEach(this.addPoint.bind(this));

最后,这似乎是最好、最简洁的方法,尽管它看起来很愚蠢。如果没有bind功能,addPoint不知道它被调用的是哪个对象,并且没有第一个this,我什至找不到我的addPoint功能。

有没有更好的方法来完成这个看似简单的事情,或者最后一行代码是推荐的方法吗?


The forEach() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach方法和其他类似的数组方法,例如map() and filter()提供一个名为的可选参数thisArg专门用于此目的。

这作为this调用函数时提供给函数的“参数”:

ptList.forEach(this.addPoint, this);

当这样的参数不可用时,则选择使用闭包变量(变量名self经常用于此)或.bind()主要是一个偏好问题。请注意,另一种选择是在构造函数中定义函数并捕获闭包中的所有内容:

function Curve(ptList) {
  var pts = [];
  function addPoint(p) {
      pts.push(p);
  }

  if(ptList.length > 2) {
    ptList.forEach(addPoint);
  }

  this.addPoint = addPoint;
}

这比将函数放在原型上需要更多的内存,因为每个实例都有自己的副本(并且还排除了原型允许您执行的一些操作),但 Douglas Crockford(JSON 和 JSLint 的发明者)最近表示他甚至不使用this不再这样了,理由是内存很便宜,但 CPU 周期却不便宜(遍历原型链需要大量的处理)。

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

在 forEach 中调用类函数:Javascript 如何处理“this”关键字 的相关文章

  • 如何减少顶点图中折线图的线条粗细

    我在角度项目中使用 Apex 图表 我在那里实现了时间序列图表 但无法减少折线图中的 线条粗细 这是我的配置 public initChartData void this series this response data data thi
  • 使用 Selenium 自动化结帐流程时出现 403

    我正在尝试使用 python 和 selenium 创建一个脚本来自动执行 bestbuy ca 的结帐过程 我一直到达最后阶段 您可以单击以查看最终订单 但当我尝试单击到最后一步时 收到以下 403 禁止消息 如网络响应中所示 是否有服务
  • jquery/javascript setInterval

    目前我正在开发一个用户通知提醒消息功能 我设法使用setInterval控制我的 Ajax 调用 检查是否有用户的通知消息 但我的问题是我只想要通知消息 在页面上出现一次 现在它在屏幕上显示多个通知警报消息 我知道你可以使用setTimeo
  • 如何创建要添加到 JavaScript 对象变量的动态键 [重复]

    这个问题在这里已经有答案了 我正在尝试类似的事情 但这个例子不起作用 jsObj for var i 1 i lt 10 i jsObj key i example 1 我该怎么做才能制作这样的动态密钥 方括号 jsObj key i ex
  • 服务器重新启动时显示等待页面

    我有一个服务器并为其创建一个 Web 界面 如果用户按下页面上的重新启动按钮 则用户将被重定向到reboot php他应该看到一个旋转 gif 直到服务器再次可访问并且服务器通过 shell 执行重新启动 如果服务器可以访问 那么我需要重定
  • 如何使用 JavaScript 或 jQuery 从 URL 下载文件?

    我使用 jQuery fileDownload 插件从 URL 下载文件 fileDownload url contentType text csv contentDisposition attachment filename url sp
  • 单击浏览器后退按钮时,将用户带回到他们在上一页滚动到的位置

    当用户按下浏览器中的后退按钮时 是否可以将用户带回到他们向下滚动到的页面区域 如 pageA 是屏幕大小的两倍 因此您必须滚动才能阅读更多内容 您单击 pageA 上的链接转到新页面 pageB 阅读后 您在浏览器中单击 返回 现在 当您返
  • 如何在 Rollup 中配置从多个输入文件仅生成单个输出文件?

    配置Rollupjs生成库时 如果输入是由多个javascript文件组成的数组 我们如何才能将这些输入生成为一个输出 js 文件呢 export const lgService input src app services livegiv
  • 如何在Keystone.js List Map中指定多个字段?

    想知道如何在 Keystone js List Map 中指定多个字段 例如 基于 Keystone 数据模型文档 http keystonejs com docs database http keystonejs com docs dat
  • 如何从主体上的 onClick 事件获取鼠标单击的绝对位置?

    我试图获取鼠标单击相对于浏览器 主体的绝对位置 顶部和左侧 not主体内的任何父元素 我有一个绑定到 body 的侦听器 但 e pageX 和 e pageY 为我提供了相对于 div 的位置 请注意 我可以利用 jQuery 和 YUI
  • 如何在D3中导入json数据?

    如何在D3中导入json文件 I did d3 json temp json 但是我如何在进一步的代码中访问这个数据集呢 到目前为止我已经尝试过 var data d3 json temp json 但使用 data data 在其余代码中
  • 无法读取未定义的属性“messageHandlers”

    我想将 JavaScript 变量传递给 Swift 我在 JavaScript 中遇到错误并进行了搜索 但没有得到任何结果 错误是 类型错误 无法读取未定义的属性 messageHandlers 任何人都可以帮忙吗 我在 Xcode 中的
  • 在 JavaScript 中给变量字符串加上引号

    我有一个 JavaScript 变量 var text http example com 文本可以是多个链接 如何在变量字符串周围放置 例如 我希望字符串看起来像这样 http example com var text http examp
  • 带条件的 Array.join()

    我该如何使用Array join 有条件的函数 例如 var name aa bb var s name join 输出是 aa bb 我想添加一个条件 仅显示不为空的单词 aa bb 您可以使用Array filter https dev
  • 如何仅使用 Javascript 减慢平滑滚动的默认速度?

    我的目标是按回车键 然后让网站滚动到底部 我已将滚动行为设置为平滑 一切都正常工作 除了平滑滚动的默认速度太快了 我怎样才能减慢它的速度 下面是我的代码 请不要使用jquery 谢谢你 document body onkeyup funct
  • 尝试利用?

    我看到我的 nopCommerce 网站记录了以下搜索 ADw script AD4 alert 202 ADw script AD4 我有点好奇他们想要完成什么 我搜索了一下 似乎是ADw script AD4 以 UTF7 编码为
  • 在画布中的鼠标位置放大/缩小

    我正在尝试使用 p5 js 实现缩放功能 当前缩放级别以及 x 和 y 位置存储在controls view目的 默认位置或 0 0 位置位于左上角 问题是调整放大 缩小时的 x 和 y 位置值 以便无论视图的当前位置是什么 它都会停留在缩
  • 无法在heroku上推送node.js应用程序

    我尝试在heroku 上推送我的node js 应用程序 但是 无法检测到此应用程序的默认语言 我什至尝试过heroku buildpacks set heroku nodejs 但还是无法推动 Counting objects 31 do
  • 脚本和链接标签的简写 http:// 为 // ?有人以前看过/用过这个吗?

    问题如下 如果您使用 addthis 共享按钮 查看任何网站 一旦您浮动在 addthis 按钮上 并且加载了所有必需的资源 请使用 firebug 或 chrome 检查器查看文档的正文 不是源代码 而是屏幕上的实际文档 对象检查器 你会
  • 监听鼠标事件……除了 div 的溢出:滚动滚动条?

    关于如何监听 mousedown 的任何建议 document exceptdiv 的溢出 滚动滚动条 我不确定滚动条是什么元素is为了参考它 您可以使用以下命令自行检查目标 document on mousedown function e

随机推荐

  • 如何使用 OAUTH2 从 Java 访问 Outlook.office365.com IMAP?

    由于 Microsoft 宣布很快将无法再通过基本身份验证访问 Outlook IMAP 邮箱 因此我正在尝试弄清楚如何在 Java 中使用 OAUTH2 正确打开 IMAP 邮箱 但我总是收到错误代码 A1 NO AUTHENTICATE
  • 将文本流从 NodeJS 传递到浏览器

    我正在尝试将 NodeJS 中处理的文本文件流式传输到浏览器 以下是处理前的文本文件 该文件名为 dbUsers json userId 443 email email protected cdn cgi l email protectio
  • 使用 RestSharp 根据请求添加证书

    我正在尝试与服务器通信 该服务器向我发送证书和私钥 以便成功执行我的请求 为了测试服务器 我使用Postman https www getpostman com 所以我在邮递员中填写了证书设置 并且我的请求工作正常 现在我想在 C 中做同样
  • 如何绑定谷歌云转发规则IP地址并发送?

    我已按照说明进行操作使用协议转发 https cloud google com compute docs protocol forwarding 在谷歌云平台上 所以我现在有这样的东西 gcloud compute forwarding r
  • Ninject 约定与 Ninject 工厂扩展将多种类型绑定到一个接口

    我正在尝试扩展标题为 SO 的问题中提出的场景Ninject Factory Extension 将多种具体类型绑定到一个接口 https stackoverflow com q 14451066 533958通过使用 Ninject Co
  • Swagger UI 上的服务器响应为空

    我有一个与 Swagger UI 集成的 REST API 但是 当我尝试从 Swagger UI 执行请求时 该界面仅向我显示curl 命令 但不提供服务器响应 从命令行运行时 curl 命令会返回预期的响应 但 UI 本身中没有显示任何
  • '\r':找不到命令[重复]

    这个问题在这里已经有答案了 echo Select your option echo 1 Change ip address echo 2 Add route echo 3 Reboot echo 4 Exit read A case A
  • 如何:使用 MvcContrib.Pagination 而不使用 MvcContrib.Grid 视图

    这最初是一个问题 但随着我做了一些实验 变成了一个解决方案 所以我想我会和大家分享这个 我的问题是 如何在不使用 MvcContrib Grid View 的情况下使用 MvcContrib Pagination 我的回答如下 我正在构建一
  • GIT hook -> Python -> Bash:如何读取用户输入?

    我正在 Python 3 5 中做一个 GIT 钩子 python 脚本调用 Bash 脚本 该脚本使用以下命令读取用户的输入read命令 bash 脚本本身可以工作 在直接调用 python 脚本时也可以 但是当 GIT 运行用 Pyth
  • 排除elasticsearch结果数据中的_id和_index字段

    如果简单地点击 api 每个文档中有 5 个字段 但我只想要这两个字段 user id 和 loc code 所以我在字段列表中提到 但它仍然返回一些不必要的数据 如 shards hits time out等 使用下面的查询在 chrom
  • 根据 TypeScript 中的参数值更改返回类型

    我有以下功能 function doThing shouldReturnObject boolean string object return shouldReturnObject hello world hello world 我希望返回
  • 在 SBT 中显示调试模式的时间戳?

    我的sbt更新很慢 我想看看详细情况 所以我有 sbt debug update gt sbtupdate log 问题是日志没有每一行的时间戳 如何启用它 据我所知 仅使用 SBT 选项是不可能的 然而这question https st
  • 在 Mac OS Catalina (10.15.7) 上安装 greenlet

    我想在我的 Mac OS Catalina 10 15 7 上运行基于 Python 的项目的本地副本 项目使用诗歌作为 Python 依赖项管理工具 在安装 python 依赖项时 它会在遵守 Greenlet 包时崩溃 我听说此类问题可
  • django admin list_filter“或”条件

    抱歉 如果这个问题之前已经被回答过 但我做了很多谷歌搜索但没有成功 我知道如何创建自定义list filter管理视图中的 s 例如子类化SimpleFilter 我真正想要的是一种方法 在管理列表视图上 检查 将它们组合在 OR 公式中的
  • 关闭 popoverview 后恢复第一响应者

    我在主视图控制器上有一个文本视图 我在视图控制器的导航栏上有一个栏按钮项目 当应用程序启动时 我执行以下操作 点击文本视图开始编辑并显示键盘 点击栏按钮以显示弹出视图 在不关闭弹出窗口视图的情况下 我关闭了键盘 通过点击屏幕上的任何其他视图
  • 更改 Windows.Ribbon 背景颜色

    我正在与System Windows Ribbon在我的项目中 我还使用其他一些库 例如AvalonDocking 我想做的是在应用程序中创建自己的主题 以便用户可以选择喜欢的主题 问题是我不明白RibbonTab更改为正确的颜色 当我更改
  • libdmtx 死了吗,建议替换吗?

    我一直在使用libdmtx http www libdmtx org在一个项目中并希望更新到较新的版本 但该项目似乎已经一年多没有更新了 最后一次更新 版本是 2011 年 6 月 Git 存储库 http libdmtx git sour
  • Safari 中的文本阴影被切断/不渲染超出元素边框

    正如标题所说 我有一个文本阴影 其中包含以下内容 body background white h1 color black text shadow 100px 100px 10px black In the Safari browser t
  • Selenium Python:没有这样的文件或目录:“/usr/local/bin/chromedriver”,但它存在并添加到路径中

    尝试在 Docker Apline Linux 上运行 selenium python 并收到 消息 chromedriver 可执行文件需要位于 PATH 中 错误 因为它认为该文件不存在 但在其他答案中尝试了我能做的一切 但它仍然无法启
  • 在 forEach 中调用类函数:Javascript 如何处理“this”关键字

    我是 Javascript 新手 只是想确保我理解它如何处理this关键字 因为 嗯 看起来很混乱 我已经在 StackOverflow 上查看了类似的问题 并想确保我没有继续错误的想法 所以我定义一个像这样的类 并且想要处理构造函数中收到