繁体   English   中英

在函数javascript中调用函数

[英]Calling a function inside a function javascript

我在jQuery ajax调用success: function(d)的成功函数中包含以下代码success: function(d)

for (var n in d.items)
{        
    google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function() {
        focusMarker(d.items[n].id);
    });
}

不幸的是,该函数始终将d.items[n].id评估为d.items集合中的最后一项。

我尝试进行此修改:

for (var n in d.items)
{        
    var id = d.items[n].id;        
    google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function() {
        focusMarker(id);
    });
}

但是我的函数总是返回同一件事。

这是一个范围问题,还是我的函数定义有问题?

有几种方法可以解决此问题,最常见的方法是使用一个函数来保存循环值:

for (var n in d.items) {
  (function(id) {
    google.maps.event.addListener(markers[id], 'mouseover', function() {
        focusMarker(id);
    });
  })(d.items[n].id);
}

顺便说一句,如果d.items是一个数组,我建议您使用顺序循环,例如:

for (var n = 0; n < d.items.length; n++) {
  //..
}

for-in语句旨在用于枚举对象属性。

如果在数组或类似对象的数组上使用它,可能会给您带来一些问题,首先,还会枚举继承的属性,这意味着如果有人扩充了Array.prototype对象,这些属性也会在循环中枚举。

同样,规范不能保证迭代的顺序,可能无法按数字顺序访问属性。

您可以关闭:

for (var n in d.items)
{        
    (function(id) {        
      google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function() {
          focusMarker(id);
      });
    })(d.items[n].id)
}

这是一个范围问题。 您想要做的是使用这样的闭包:

for (var n in d.items)
{        
    (function(id){
        google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function() {
            focusMarker(id);
        });
    })(d.items[n].id);
}

是的,这是一个范围问题,也是一个很常见的问题。

闭包中包含的变量共享相同的单一环境,因此,在调用mouseover回调时, for in循环将运行,并且n变量将指向其最后分配的值。

您可以使用函数工厂使用更多的闭包来解决此问题:

function makeOnHoverHandler(id) {  
  return function () {  
    focusMarker(id);
  };  
}

// ...

for (var n in d.items) {        
  google.maps.event.addListener(markers[d.items[n].id], 
                                'mouseover', 
                                makeOnHoverHandler(d.items[n].id));
}

如果您不熟悉闭包的工作原理,那么这可能是一个棘手的话题。 您可能需要查看以下Mozilla文章以进行简要介绍:

您也可以内联以上代码。 这实际上是一种更常见的方法,但实际上与上面的方法相同:

for (var n in d.items) {        
  google.maps.event.addListener(markers[d.items[n].id], 'mouseover', (function (id) {
    focusMarker(id);
  })(d.items[n].id));
}

还有另一种解决方案是通过使用自调用匿名函数将每个迭代包含在自己的范围内:

for (var n in d.items) {
  (function (id) {
    google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function () { 
      focusMarker(id);
    });
  })(d.items[n].id);
}

与其他响应类似,但我认为内联定义的内容更简洁,更简洁:

for (var n in d.items)
{        
    google.maps.event.addListener(markers[d.items[n].id], 'mouseover', new function() {
        return function() {
            focusMarker(d.items[n].id);
        }
    });
}

您可能想知道new function()作用。 一次声明并执行一个函数。 它基本上是:

for (var n in d.items)
{        
    google.maps.event.addListener(markers[d.items[n].id], 'mouseover', function() {
        return function() {
            focusMarker(d.items[n].id);
        }
    }());
}

尽管我认为第二个示例可能不起作用,但是因为如果您不将结果分配给变量,则需要额外的括号。 例如:

function() { alert("hi"); }();

是语法错误。 必须:

(function() { alert("hi"); })();

内联作为函数参数算作赋值吗? 我不知道。 最好坚持我的第一个例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM