创建含至少两个方法的对象:按钮事件绑定this指向异常的解决咨询
解决JavaScript事件绑定中this指向对象实例的问题
当然可行!你遇到的this指向问题在JS事件绑定里真的太常见了,咱们来一步步搞定它~
问题根源
当你直接把this.print传给jQuery的on方法时,事件触发时,这个函数的上下文(也就是this)会被自动改成触发事件的DOM元素——也就是你的按钮#but。所以print方法里的this.attribute自然拿不到obj实例的42啦。
几种解决方案
1. 使用bind()(你尝试过的方法,正确用法在这里)
bind()方法会创建一个新函数,强制把函数的this绑定到你指定的对象上。修改你的eventer方法就行:
obj.prototype.eventer = function() { $("#but").on("click", this.print.bind(this)); }
这里的bind(this)里的this是eventer方法执行时的上下文,也就是obj的实例,所以新生成的函数在触发时,this会一直指向这个实例。
2. 用ES6箭头函数
箭头函数不会绑定自己的this,它会继承外层作用域的this。这样写也能解决问题:
obj.prototype.eventer = function() { $("#but").on("click", () => { this.print(); }); }
箭头函数里的this就是eventer里的obj实例,调用this.print()时,print方法的this自然也是这个实例。
3. 提前保存this到变量(兼容旧浏览器)
如果你的项目需要兼容不支持ES6的环境,可以在eventer里先把实例的this存起来:
obj.prototype.eventer = function() { const self = this; // 把当前实例的this存到self里 $("#but").on("click", function() { self.print(); // 用self调用print,此时print的this指向实例 }); }
修改后的完整代码示例(用bind的版本)
function obj() { this.attribute = 42; this.eventer(); } obj.prototype.eventer = function() { $("#but").on("click", this.print.bind(this)); } obj.prototype.print = function() { $("#print").html(this.attribute); } var test = new obj();
对应的HTML:
<script src='//code.jquery.com/jquery.min.js'></script> <button id="but">Click me !</button> <div id="print"></div>
现在点击按钮,#print里就会显示42啦!
内容的提问来源于stack exchange,提问作者Nix
相关产品推荐
相关产品推荐

