为何事件监听器调用的内部函数中this指向会发生变化?
JavaScript中this指向的问题解析
为什么display函数里的this指向window?
- 事件监听器的外层匿名函数是作为事件处理函数被调用的,这种场景下JavaScript会自动将
this绑定为触发事件的DOM元素(也就是你的按钮)。 - 而
display()属于普通函数调用,在非严格模式下,普通函数执行时this默认指向全局对象(浏览器环境中就是window)。this的指向由调用方式决定,和函数定义的位置无关——哪怕它嵌套在另一个函数里,只要是普通调用,this就会指向全局对象。
让display的this指向按钮的几种方法
方法1:用变量保存外层的this
在回调函数里先把this存入一个变量(比如that),利用词法作用域的特性,内部函数可以访问到这个变量:
document.getElementById('myButton').addEventListener('click', function() { console.log(this); const that = this; // 保存外层指向按钮的this function display() { console.log(that); // 使用保存的变量替代this } display(); });
方法2:用bind绑定this
通过bind方法给display函数永久绑定外层的this,这样无论后续怎么调用display,它内部的this都不会改变:
document.getElementById('myButton').addEventListener('click', function() { console.log(this); function display() { console.log(this); } const boundDisplay = display.bind(this); // 绑定this到按钮 boundDisplay(); });
方法3:使用箭头函数
箭头函数没有自己的this,它会直接继承外层作用域的this,把display改成箭头函数就能自动复用外层指向按钮的this:
document.getElementById('myButton').addEventListener('click', function() { console.log(this); const display = () => { // 改用箭头函数 console.log(this); } display(); });
方法4:调用时用call/apply指定this
调用display的时候,用call或apply方法直接传入想要绑定的this:
document.getElementById('myButton').addEventListener('click', function() { console.log(this); function display() { console.log(this); } display.call(this); // 调用时强制指定this为按钮 });
内容的提问来源于stack exchange,提问作者Navjot Gill
相关产品推荐
相关产品推荐

