Javascript 使用addEventListener运行时“不是函数”

Javascript 使用addEventListener运行时“不是函数”,javascript,Javascript,当我点击按钮时,它运行函数fillonel。然而SmallBattle.FillandTransferTworth并不是一个函数 当我在代码中单独运行FillonEll函数而不使用click事件时,它工作得非常好 为什么在我运行click事件时它停止工作 在没有单击事件的情况下运行FillonEll函数时,一切正常 class Bottle { constructor( maxVolume ) { this.maxVolume = maxVolume; }

当我点击按钮时,它运行函数fillonel。然而SmallBattle.FillandTransferTworth并不是一个函数

当我在代码中单独运行FillonEll函数而不使用click事件时,它工作得非常好

为什么在我运行click事件时它停止工作

在没有单击事件的情况下运行FillonEll函数时,一切正常

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);
})


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

浏览器的click事件不知道您的瓶子对象,并且没有浏览器希望将这些对象传递给事件处理程序。传递给事件处理程序的参数为。所以在这段代码中:

smallButton.addEventListener('click', function(smallBottle, bigBottle){
    fillOneLiter(smallBottle, bigBottle);
})
此函数中的SmallBattle参数是一个事件对象,然后将其传递给FillonEll,FillonEll然后尝试在该事件对象上调用FillandTransfer两次。该函数不在事件对象上

如果希望事件处理程序始终使用相同的瓶子对象,则可以完全忽略函数参数,只使用页面范围的变量:

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

这样,在函数的作用域中就不会有新的smallBottle和bigBottle变量,而是使用更高作用域中的变量。

要修复此代码,只需替换以下内容:

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

将函数传递给addEventListener时,该函数的第一个参数应该是表示所发生事件的对象。因此,在您的错误代码中,smallBottle被假定为事件对象——它当然没有FillandTransferTworth方法。这就是为什么你会收到错误,抱怨它不是一个函数,因为undefined确实不是一个函数


您只需要在单击发生时运行FillonEll函数,并使用您预先知道的参数。这就是正确版本的功能。

非常感谢您的回答!我现在明白了:D
smallButton.addEventListener('click', function(){
    fillOneLiter(smallBottle, bigBottle);
})