javascript - 使用 addEventListener 运行时为 "Not a function"

标签 javascript

当我单击该按钮时,它会运行函数 fillOneLiter。然而,smallBottle.fillAndTransferTwice() 说不是一个函数。

当我在没有点击事件的代码中单独运行 fillOneLiter 函数时,它工作得很好。

为什么当我通过点击事件运行它时它停止工作?

当我在没有点击事件的情况下运行 fillOneLiter 函数时,一切正常。

class Bottle {

    constructor( maxVolume ) {
        this.maxVolume = maxVolume;
    }

    currentVolume = 0;

    empty() {
        this.currentVolume = 0;
    }

    fill(target) {
        while (this.currentVolume !== 0 && target.currentVolume !== target.maxVolume) {
            this.currentVolume--;
            target.currentVolume++;
        }
    }

    transfer(target) {
        this.fill(target);
    }

    fillAndTransfer(target) {
        this.currentVolume = this.maxVolume;
        this.fill(target);
    }

    fillAndTransferTwice(target) {
        var i;
        for ( i=0; i<=2; i++) {
            this.currentVolume = this.maxVolume;
            this.fill(target);
        }
    }
}

var fillOneLiter = (smallBottle, bigBottle) => {
    smallBottle.fillAndTransferTwice(bigBottle);

    bigBottle.empty();
}

var fillFourLiter = (smallBottle, bigBottle) => {
    smallBottle.fillAndTransferTwice(bigBottle);

    bigBottle.empty();
    smallBottle.transfer(bigBottle);
    smallBottle.fillAndTransfer(bigBottle);
}

var smallBottle = new Bottle(3);
var bigBottle = new Bottle(5);

const threeLiter = document.getElementById('small-bottle-volume');
const smallButton = document.getElementById('first-button');

smallButton.addEventListener('click', function(smallBottle, bigBottle){
    fillOneLiter(smallBottle, bigBottle);
})

我很好奇为什么当我通过点击事件监听器运行该函数时,方法 fillAndTransferTwice 在函数 fillOneLiter 中不起作用。如果我只是在没有事件的情况下运行 fillOneLiter,那么 fillAndTransferTwice 方法就可以正常工作。

最佳答案

浏览器的点击事件不知道您的 Bottle 对象,并且浏览器不会期望将这些对象传递给事件处理程序。传递给事件处理程序的参数是 the event object 。所以在这段代码中:

smallButton.addEventListener('click', function(smallBottle, bigBottle){
    fillOneLiter(smallBottle, bigBottle);
})

此函数中的 smallBottle 参数是一个事件对象,然后您将其传递给 fillOneLiter,后者会尝试调用该事件的 fillAndTransferTwice事件对象。该函数不在事件对象上。

如果您希望事件处理程序始终使用相同的 Bottle 对象,那么您可以完全省略函数参数,而仅使用页面范围的变量:

smallButton.addEventListener('click', function(){
    fillOneLiter(smallBottle, bigBottle);
})

这样,您就不会在函数作用域中添加新的 smallBottlebigBottle 变量,而是使用更高作用域中的变量。

关于javascript - 使用 addEventListener 运行时为 "Not a function",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56716396/

相关文章:

javascript - 使用 php 和 html 自动完成

Javascript 用另一个对象更新对象

javascript - Accordion 从 localStorage 变量中设置为事件状态

javascript - 子状态解析注入(inject)到父 Controller 中

javascript - 在 Node.js 中反序列化后将对象与其类重新关联

javascript - 带有 promise 的 jQuery 验证

javascript - AngularJS 范围变量在某处使用 $http 时不起作用

javascript - Canvas 元素无法在 iOS 设备上呈现

javascript - 无法从自定义 AngularJS 过滤器更新 Controller 的范围级别属性

javascript - 循环遍历 DOM 元素和子元素来创建 JS 数组 - 无法理解实现此目的的最佳方法