You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中处理this指针与自定义参数的最优方案及事件监听困惑

我太懂这种在类方法里写事件监听时,this突然“变味”的困惑了!你的核心问题是事件回调函数里的this默认指向触发事件的DOM元素(也就是那个删除按钮),但你大概率想在回调里同时访问Sample实例的attra、attrb这些属性,还有按钮本身,对吧?

先把你的原始代码补全并修正细节(比如补上变量声明、修正addEventListener的拼写),方便对照:

Sample.prototype.myfunc = function my_func() {
  this.attra = someValue;
  this.attrb = someValueb;
  // 补上const/let避免全局变量
  const tmpDelNode = this.doc.createElement('span');
  tmpDelNode.innerHTML = '<span class="del">X</span>';
  this.newAttachmentContainer.appendChild(tmpDelNode.firstChild);
  const delbtn = this.doc.querySelector('.del');
  // 这里的回调里this会指向delbtn,而非Sample实例
  delbtn.addEventListener('click', function() {
    console.log(this); // 输出的是<span class="del">X</span>,不是Sample实例
    // 想访问this.attra?这里根本拿不到!
  });
};

下面给你三种常用的解决思路,按需选择:

方法1:用箭头函数继承外层this

箭头函数不会绑定自己的this,会直接沿用父作用域(也就是myfunc方法里的this,即Sample实例)的this。如果要访问按钮本身,用event.target即可:

Sample.prototype.myfunc = function my_func() {
  this.attra = someValue;
  this.attrb = someValueb;
  const tmpDelNode = this.doc.createElement('span');
  tmpDelNode.innerHTML = '<span class="del">X</span>';
  this.newAttachmentContainer.appendChild(tmpDelNode.firstChild);
  const delbtn = this.doc.querySelector('.del');
  
  delbtn.addEventListener('click', (event) => {
    console.log(this.attra); // 完美访问Sample实例的属性!
    console.log(event.target); // 拿到触发事件的删除按钮
  });
};

方法2:用bind()把this绑定到实例

如果习惯用普通函数写回调,可以用bind()强制把回调的this绑定到Sample实例,同样用event.target访问按钮:

Sample.prototype.myfunc = function my_func() {
  this.attra = someValue;
  this.attrb = someValueb;
  const tmpDelNode = this.doc.createElement('span');
  tmpDelNode.innerHTML = '<span class="del">X</span>';
  this.newAttachmentContainer.appendChild(tmpDelNode.firstChild);
  const delbtn = this.doc.querySelector('.del');
  
  // 先定义回调函数
  const handleDelete = function(event) {
    console.log(this.attra); // this是Sample实例
    console.log(event.target); // 按钮元素
  };
  
  // 绑定this后再添加监听
  delbtn.addEventListener('click', handleDelete.bind(this));
};

方法3:保存外层this到变量(传统写法)

在myfunc里把实例的this存到一个变量(比如self或that),然后在回调里用这个变量访问实例,此时普通函数里的this还是指向按钮:

Sample.prototype.myfunc = function my_func() {
  const self = this; // 把Sample实例的this存起来
  this.attra = someValue;
  this.attrb = someValueb;
  const tmpDelNode = this.doc.createElement('span');
  tmpDelNode.innerHTML = '<span class="del">X</span>';
  this.newAttachmentContainer.appendChild(tmpDelNode.firstChild);
  const delbtn = this.doc.querySelector('.del');
  
  delbtn.addEventListener('click', function(event) {
    console.log(self.attra); // 用self访问实例属性
    console.log(this); // 这里的this还是删除按钮
  });
};

额外小提示

如果页面上会有多个.del按钮,querySelector只会返回第一个匹配的元素,建议直接给刚创建的按钮加监听,不用去DOM里查找:

// 直接获取刚创建的删除按钮,省去querySelector的步骤
const delbtn = tmpDelNode.firstChild;
delbtn.addEventListener('click', ...);

内容的提问来源于stack exchange,提问作者Suganya Selvarajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:41:35