对javascript工作原理的误解

对javascript工作原理的误解,javascript,jquery,Javascript,Jquery,我将事件绑定到客户端的一个通道,该通道等待来自服务器的消息,并在回调中触发匿名函数,在thing参数中传递消息数据 channel.bind('coordinates_sent', function(thing) { var x = thing.left; var y = thing.top; $(window).scroll(function(){ alert(x + " " + y); }); alert(x + "

我将事件绑定到客户端的一个通道,该通道等待来自服务器的消息,并在回调中触发匿名函数,在
thing
参数中传递消息数据

channel.bind('coordinates_sent', function(thing) {
     var x = thing.left;
     var y = thing.top;

     $(window).scroll(function(){
           alert(x + " " + y);
     });

     alert(x + " " + y);
});
滚动
方法之外的警报消息按预期工作。当新消息到达时,它会立即通知服务器发送的数据的新x和y坐标

但是,滚动消息中的警报消息的行为与我预期的不同。如果已向事件侦听器发送一条消息,则每次滚动时,警报都会正确显示该消息的x和y坐标。但是,如果收到另一条消息,警报将首先显示第一条消息中的原始x和y坐标,然后显示最近一条消息中的x和y坐标


我无法理解为什么会发生这种情况。

每当您从服务器收到消息时,都会附加一个新的
滚动事件处理程序。附加事件侦听器时,不会删除现有侦听器。当用户滚动时,将执行所有附加的事件处理程序

若要解决此问题,请将其附加
滚动
事件的部分移动到服务器接收的消息的事件处理程序之外:

var x, y;
channel.bind('coordinates_sent', function(thing) {
    x = thing.left;
    y = thing.top;

    alert(x + " " + y);
});
$(window).scroll(function(){
    alert(x + " " + y);
});

bind()方法注册处理程序,但不解除它们的绑定。尝试改用.one(),请参见。

在匿名函数中,
x
y
不是局部作用域吗?@Justin:哦,说得对。你想达到什么目的?当用户滚动时,显示从服务器收到的最后一个坐标?是的,准确地说,如果
滚动
事件处理程序在回调中,但如果有办法,请首先删除所有
滚动
事件处理程序?@Justin:如果您保留了对最后一个可以工作的坐标的引用(您将使用
解除绑定
),但是如果你看一下我更新的答案,我认为这可能会更简单。这样就可以了,但我不想污染全局名称空间。也许如果您将所有这些都封装在一个自调用函数中,那么代码可能会变得混乱