我有两个 JavaScript 函数,一个将事件处理程序附加到整个元素类,另一个在激活事件处理程序时调用:
function attachDefinition(obj) {
var classArr = document.getElementsByClassName("flashcards");
for (let i = 0, len = classArr.length; i < len; i++) {
classArr[i].addEventListener('click', cardClicked);
}
}
function cardClicked(obj) {
console.log(this.id);
console.log(obj);
var img = document.createElement('img');
img.src = 'https://www.wordnik.com/img/wordnik_badge_a2.png';
document.getElementById(this.id).innerHTML = '';
document.getElementById(this.id).appendChild(img);
}
上面的函数在点击时运行没有错误。记录到控制台的 this.id
显示被单击的 div
元素的 id,obj 记录全局对象。
这很好,但是我需要传入在程序中的不同函数中创建的对象。上面的代码只需要将 obj 参数添加到 addEventListener 调用中,但是当我这样做时,一切都会崩溃。这段代码:
function attachDefinition(obj) {
var classArr = document.getElementsByClassName("flashcards");
for (let i = 0, len = classArr.length; i < len; i++) {
classArr[i].addEventListener('click', cardClicked(obj)); //only thing I've changed!
}
}
function cardClicked(obj) {
console.log(this.id);
console.log(obj);
var img = document.createElement('img');
img.src = 'https://www.wordnik.com/img/wordnik_badge_a2.png';
document.getElementById(this.id).innerHTML = '';
document.getElementById(this.id).appendChild(img);
}
现在控制台成功记录了传入的对象,但记录 this.id
的行现在未定义,并且我在innerHTML行上收到“无法设置未定义或空引用的属性'innerHTML'”。
我很难理解为什么传入参数会改变this
以及如何修复它。
最佳答案
如果我们假设您的
classArr[i].addEventListener('click', cardClicked(obj);
确实
classArr[i].addEventListener('click', cardClicked(obj));
// Note ---------------------------------------------^
这就是调用 cardClicked
并将其返回值传递给 addEventListener
,与 foo(bar())
完全相同> 调用 bar
并将其返回值传递给 foo
。
但是 addEventListener
需要第二个参数中有一个函数,而 cardClicked
不返回函数。
相反,由于您依赖 this
引用 cardClicked
内的单击元素,因此您需要:
classArr[i].addEventListener('click', function() {
cardClicked.call(this, obj);
});
或
classArr[i].addEventListener('click', cardClicked.bind(classArr[i], obj));
第一个方法是通过调用 cardClicked
来响应点击,这样它看到的 this
与匿名函数的 this
相同收到。
第二个方法是使用 Function#bind
创建一个新函数,在调用该函数时,将调用 cardClicked
并将 this
设置为classArr[i]
的 avlue 及其第一个参数设置为 obj
。
关于javascript - "this"当参数传递给函数时停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38731966/