Javascript 调用成员方法时出现类型错误问题

Javascript 调用成员方法时出现类型错误问题,javascript,ecmascript-6,Javascript,Ecmascript 6,我正在使用ES2016编写一个类,我不明白为什么,控制台向我抛出了这个错误 我四处寻找可能的原因,但: 它不可能是函数名的输入错误,我已经检查了一遍又一遍,函数声明和我用来调用它的函数名是匹配的 highlightSelected不与任何预先存在的属性共享其名称 我在highlightSelected函数中执行的所有操作都允许在作为参数传递的变量类型上执行 那么到底发生了什么?为什么这不起作用 Uncaught TypeError: this.highlightSelected is not

我正在使用ES2016编写一个类,我不明白为什么,控制台向我抛出了这个错误

我四处寻找可能的原因,但:

  • 它不可能是函数名的输入错误,我已经检查了一遍又一遍,函数声明和我用来调用它的函数名是匹配的
  • highlightSelected
    不与任何预先存在的属性共享其名称
  • 我在
    highlightSelected
    函数中执行的所有操作都允许在作为参数传递的变量类型上执行
那么到底发生了什么?为什么这不起作用

Uncaught TypeError: this.highlightSelected is not a function
    at HTMLAnchorElement.<anonymous> (app.js:40) 
html{
字体大小:16px;
}
.集装箱{
宽度:85%;
利润率:4%自动;
}
#按钮区{
显示器:flex;
证明内容:周围的空间;
边缘底部:4rem;
}
#按钮区域a{
文字装饰:无;
字体系列:无衬线;
背景颜色:薄雾;
颜色:#000;
填充:.8rem 2rem;
}
#按钮区域a。当前选定{
背景颜色:紫色;
颜色:白色;
}
#产品区{
显示器:flex;
证明内容:周围的空间;
}
.产品{
字体系列:无衬线;
字号:1rem;
背景颜色:黄花;
填充:.8rem 2rem;
}

查询选择器
汽车

飞机

披萨

榕树

键盘

衬衫

香草的


您的问题在于这段代码:

registerListeners() {
  this.filterButtons.map(function(button) {
    button.addEventListener("click", function(event) {
      console.log(event.target.dataset.cat + " has been clicked!");
      if (this.lastClicked !== event.target.dataset.cat) {
        this.highlightSelected(event.target)
        this.lastClicked = event.target;
      }
    });
  });
}
问题是JavaScript使用函数作用域,因此
映射中的
addEventListener
不是
过滤器的实例。有几种方法可以解决这个问题,但对您来说,最简单的方法是使用,因为它们保留了相同的词法
this

registerListeners() {
  this.filterButtons.map((button) => {
    button.addEventListener("click", (event) => {
      console.log(event.target.dataset.cat + " has been clicked!");
      if (this.lastClicked !== event.target.dataset.cat) {
        this.highlightSelected(event.target)
        this.lastClicked = event.target;
      }
    });
  });
}

有关此方面的详细信息,请查看

当您将方法绑定到事件时,
不再是类。要保留上下文,可以使用中间变量:

这个例子显示了这个问题

window.setTimeout(this.showText, 50);
showText方法将被正确调用,但在该方法中使用此方法将导致。。。修正:

let _this = this;
window.setTimeout(function () { _this.showText(); }, 50);

您还可以使用
bind
apply
或箭头函数来实现相同的效果。这是一只可以用多种方式剥皮的猫。箭头函数具有与ECMAScript类类似的浏览器支持,因此,如果您这样做,您将不会丢失任何浏览器。

您需要将事件回调与该类绑定。由于该类标记为ES6,因此您应该使用
for…of
而不是
map
,而使用箭头函数(未绑定!)
函数
表达式。