【问题标题】:Removing A Function from an Array从数组中删除函数
【发布时间】:2018-02-11 01:30:09
【问题描述】:

我有一个函数数组,我正在尝试像 c# 中的委托事件一样使用它们。

我将一个函数推送到数组中,当数组循环遍历函数时,它将被调用。

问题是我在完成后无法删除该功能,这有悖于目的。

这是我的代码。我完全愿意用不同的方法来做这件事,我对 JS/JQ 还很陌生,所以这就是我想出的。

var MouseMoveFunctions = [];

$(document).ready(function(){
    
    //Create the event to call our functions.
    $(document).mousemove(function(e){
        CallMouseMoveFunctions(e);
    });
   
});

function CallMouseMoveFunctions(e){  
    //Only continue if there is atleast 1 function in the array.
    if(MouseMoveFunctions.length == 0) return;
    
    //Call each function in the array.
    for(var i = 0; i < MouseMoveFunctions.length;i++){
        MouseMoveFunctions[i](e);
    }
}



$(document).ready(function(){
    //Add the TrackMouse function to the array.
    MouseMoveFunctions.push(function(event){TrackMouse(event)});
});




var mX = 0;
var mY = 0;

function TrackMouse(e){
     mX = e.pageX;
     mY = e.pageY;    
    
    var index = MouseMoveFunctions.indexOf(function(event){TrackMouse(event)});
    alert(index); //Always coming up -1, so it isn't getting removed
    
    //Try and remove the function if it exists, just for now so I know its working
    if(index != -1){
    MouseMoveFunctions.splice(index);
    }
    
}

【问题讨论】:

    标签: javascript jquery arrays delegates


    【解决方案1】:

    //总是出现-1,所以它不会被删除

    你总是得到-1,因为你将一个唯一的函数对象传递给.indexOf(),所以它不能已经在数组中。您压入数组的匿名函数没有其他引用,因此您无法通过引用将其删除。

    因为您正在推送和删除一个仅传递事件参数的函数,所以您可以改为推送函数本身。

    MouseMoveFunctions.push(TrackMouse);
    

    那你按身份找同样的功能就可以成功找到了。

    var index = MouseMoveFunctions.indexOf(TrackMouse);
    

    请注意,如果您将同一个函数多次放入数组中,则每次都需要单独删除它。

    此外,正如 Scott 所说,您需要提供要删除的项目数。


    更好的解决方案是使用Set 而不是数组。此外,您可以摆脱那些 .ready() 处理程序。

    var MouseMoveFunctions = new Set();
    
    //Create the event to call our functions.
    $(document).mousemove(CallMouseMoveFunctions);
    
    function CallMouseMoveFunctions(e){  
        //Only continue if there is atleast 1 function in the array.
        if(MouseMoveFunctions.size == 0) return;
    
        //Call each function in the set.
        for(const fn of MouseMoveFunctions) {
            fn(e);
        }
    }
    
    //Add the TrackMouse function to the array.
    MouseMoveFunctions.add(TrackMouse);
    
    var mX = 0;
    var mY = 0;
    
    function TrackMouse(e){
         mX = e.pageX;
         mY = e.pageY;    
    
         MouseMoveFunctions.delete(TrackMouse);
    }
    

    【讨论】:

    • 这太奇怪了,我之前试图自己传递这个函数,但它不起作用。我猜它还有其他问题。不知道有没有set,是不是和c#list类似?谢谢皮特。
    【解决方案2】:

    您需要将 1 作为第二个参数传递给 splice,以告诉它删除您作为第一个参数提供的索引位置的 1 个元素。

    .splice(index, 1)
    

    【讨论】:

    • 其实不是必须的,谢谢回复。
    • @LittlrRain 如果省略,则从索引到数组末尾的所有元素都将被删除,而不仅仅是索引处的元素。
    • 啊,好吧,我想我使用它的方式没有受到影响。谢谢
    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    相关资源
    最近更新 更多