ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-06-12 05:29:38  阅读:1355  来源: 互联网

标签:javascript foreach this bind


我是Javascript的新手,只是想确保我理解它是如何处理这个关键字的,因为……好吧,它看起来很混乱.我已经在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);

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

然后我尝试了:

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

但我不能,因为只要我输入内部函数(它不再引用正在构造的Curve对象),它就会引用全局范围,因此addPoint未定义.

解决这个问题的方法是在一个范围内创建一个引用它的变量,我仍然可以在子函数中与之交谈:

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

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

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

最后,这似乎是最好,最简洁的方法,甚至认为它看起来很傻.没有bind函数,addPoint不了解它被调用的对象,没有第一个,我甚至找不到我的addPoint函数.

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

解决方法:

forEach()方法和其他类似的数组方法(如map()和filter())专门为此提供了一个名为thisArg的可选参数.

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

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的发明者)最近说他甚至不再使用它了,理由是内存便宜,但CPU周期不是(遍历原型链需要相当多的处理).

标签:javascript,foreach,this,bind
来源: https://codeday.me/bug/20190612/1223607.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有