javascript - "this"当参数传递给函数时停止工作

标签 javascript event-handling this

我有两个 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/

相关文章:

javascript - 用于选中复选框标签的 Jquery 选择器

javascript - 如何使用 momentjs 检查日期是否至少过去一天?

NHibernate 保存/更新事件监听器 : listening for child object saves

jquery - 我是否正确理解 jQuery 委托(delegate)函数?

c# - 编写事件访问器时的多线程问题

javascript - 从其他函数访问 "this"类型 JavaScript 变量

javascript - 为什么构造函数(带有 "return this")返回 window 对象?

javascript - 在拖动过程中将元素保持在鼠标下方

javascript - 将用户输入的 url 与 php 变量中的 url 进行匹配

javascript - 如何使用 'this' 关键字规避 ES6 类范围问题