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

如何在JavaScript原型中添加事件处理函数?点击失效问题排查

问题解决与思路

嘿,我来帮你拆解下遇到的两个问题:

1. 点击事件不工作的核心原因:this的指向问题

在你的点击事件回调函数里,this的指向并不是你创建的Shape实例,而是触发点击事件的那个DOM元素(也就是<div id="shape-div"></div>)。所以当你在回调里写this.shapeElement时,这个this根本没有shapeElement这个属性,自然就无法执行隐藏操作啦。

解决方法有三种,选你顺手的就行:

  • 方法一:用ES6箭头函数(推荐,写法简洁)
    箭头函数不会绑定自己的this,它会继承外层作用域的this(也就是Shape实例):

    this.shapeElement.click(() => {
      this.shapeElement.css("display", "none");
    });
    
  • 方法二:提前保存this的引用
    在回调外面把this存到一个变量里(比如that或者self),回调里用这个变量访问实例:

    const that = this;
    this.shapeElement.click(function() {
      that.shapeElement.css("display", "none");
    });
    
  • 方法三:用jQuery的$.proxy绑定this
    通过$.proxy强制把回调的this绑定到Shape实例上:

    this.shapeElement.click($.proxy(function() {
      this.shapeElement.css("display", "none");
    }, this));
    

另外还有个小坑:你在Shape构造函数里已经调用了this.draw(),但在$(document).ready里又调用了一次square.draw(),这会导致页面上生成两个形状!记得去掉ready里重复的square.draw()哦。

2. 从过程式转OOP觉得难,正常吗?

太正常了!完全不用焦虑😉。过程式编程是按步骤写“做什么”,而OOP需要你切换到“谁来做”的思维,要理解封装、实例化、this绑定这些新概念,刚开始肯定会觉得原来简单的操作变复杂了。多写几个小项目,慢慢习惯这种思维模式之后,你会发现OOP在复用性、代码组织上的优势的。

修正后的完整代码

这里用箭头函数的版本给你做了修正,还顺便把循环里的i改成了let,避免全局变量污染:

function Shape () {
  this.x = Math.floor(Math.random()*1200);
  this.y = Math.floor(Math.random()*500);
  this.draw();
}

Shape.prototype.draw = function() {
  var shapeHtml = '&lt;div id="shape-div"&gt;&lt;/div&gt;';
  var widthAndHeight = Math.floor(Math.random()*400);
  this.shapeElement = $(shapeHtml);
  this.shapeElement.css({
    'width': widthAndHeight,
    'height': widthAndHeight,
    position: "relative",
    left: this.x,
    top: this.y
  });
  this.shapeElement.css({ display: "block" });
  
  // 箭头函数解决this指向问题
  this.shapeElement.click(() => {
    this.shapeElement.css("display", "none");
  });

  $("body").append(this.shapeElement);
}

"use strict";
Shape.prototype.colour = function() {
  var colours = '0123456789ABCDEF'.split('');
  var randomColour = "#";
  for (let i = 0; i &lt; 6; i++) {
    randomColour+=colours[Math.floor(Math.random()*16)];
  };
  this.shapeElement.css({backgroundColor: randomColour});
}

$(document).ready(function() {
  var square = new Shape();
  // 去掉重复的draw调用
  square.colour();
})

内容的提问来源于stack exchange,提问作者Michael Alexander

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:40:38