2014-12-06 60 views
1

我正在通过代码学校的一个小练习,不知道为什么我必须将函数buildTicket(parkRides, fastPassQueue, wantsRide);传递给一个变量,然后调用变量上的函数来使此脚本工作。为什么我不能直接调用一个函数?

下面的代码将不会执行(我不分配功能给一个变量):

var parkRides = [ 
    ["Birch Bumpers", 40], 
    ["Pines Plunge", 55], 
    ["Cedar Coaster", 20], 
    ["Ferris Wheel", 90] 
]; 

var fastPassQueue = ["Cedar Coaster", "Pines Plunge", "Birch Bumpers", "Pines Plunge"]; 

var wantsRide = "Birch Bumpers"; 

function buildTicket(allRides, passRides, pick) { 
    if(passRides[0]==pick){ 
     var pass = passRides.shift(); 
     return function(){ 
      alert("Quick you have a fast pass to "+pass+"!"); 
     }; 
    } else { 
     for(var i = 0; i<allRides.length; i++){ 
      if(allRides[i][0] == pick){ 
       return function(){ 
        alert("A ticket is printing for "+pick+"!\n"+ 
          "Your wait time is about "+allRides[i][1]+" minutes."); 
       }; 
      } 
     } 
    } 
} 

buildTicket(parkRides, fastPassQueue, wantsRide); 

但是,如果我添加var ticket = buildTicket(parkRides, fastPassQueue, wantsRide); ticket();它工作正常。下面的完整代码:

var parkRides = [ 
    ["Birch Bumpers", 40], 
    ["Pines Plunge", 55], 
    ["Cedar Coaster", 20], 
    ["Ferris Wheel", 90] 
]; 

var fastPassQueue = ["Cedar Coaster", "Pines Plunge", "Birch Bumpers", "Pines Plunge"]; 

var wantsRide = "Birch Bumpers"; 

function buildTicket(allRides, passRides, pick){ 
    if(passRides[0]==pick) { 
     var pass = passRides.shift(); 
     return function(){ 
      alert("Quick you have a fast pass to "+pass+"!"); 
     }; 
    } else { 
     for(var i = 0; i<allRides.length; i++){ 
      if(allRides[i][0] == pick){ 
       return function(){ 
        alert("A ticket is printing for "+pick+"!\n"+ 
          "Your wait time is about "+allRides[i][1]+" minutes."); 
       }; 
      } 
     } 
    } 
} 

var ticket = buildTicket(parkRides, fastPassQueue, wantsRide); 

ticket(); 

任何有识之士,为什么我需要的功能传递给一个变量,然后调用变量将不胜感激。我相信我在这里很明显地忽略了这一点。

回答

3

您的buildTicket函数返回一个不使用参数的函数。

return function(){alert("Quick you have a fast pass to "+pass+"!"); 
     }; 

你可以用这种语法立即调用返回的功能:

例如,在你的代码,它在这里函数返回

buildTicket(parkRides, fastPassQueue, wantsRide)(); 

你也可以改变return线在function buildTicket立即警告,而不是返回一个函数,但这可能会打破buildTicket的其他用途,期望它返回一个函数,从而延迟警报,可能显示在鳕鱼的特定点以后在需要时。

+0

是否有这个语法的名称? – 2014-12-06 17:25:58

+0

非常感谢 - 解决了问题并给出了原因。我怀疑我也可以直接返回警报而不使用函数,并通过调用buildTicket(parkRides,fastPassQueue,wantsRide)获得相同的结果; – 2014-12-06 17:26:57

+0

人们用匿名版本创建局部范围,即在for循环中有一些可爱的首字母缩略词。 IIFE立即调用函数表达式等。 – Paul 2014-12-06 17:27:12

2

这应该很好!

buildTicket(parkRides, fastPassQueue, wantsRide)(); 
+0

这个工程,以及显然;) – 2014-12-06 17:27:20

1

当您使用变量ticket();你正在做一个更多的函数调用,否则你会做的。

基本上第一个buildTicket自己调用... buildTicket(parkRides,fastPassQueue,wantsRide);

看起来像......

(function buildTicket(allRides, passRides, pick) { 
    //... your code here that is returning a function 
}(parkRides, fastPassQueue, wantsRide); 

引擎盖下,并会返回一个包含尚未援引又一个警报匿名函数。看起来像......

(function() { 
    //... your code containing an alert 
}); 

,并因为它没有被绑定到变量它只是坐在那里不能被调用,因为你现在有没有对它的引用。 有两种解决此问题的方法: 1)您已经计算出将匿名函数分配给变量并使用变量调用函数。 2)是通过添加另一组parens立即调用返回的函数。

最后,他们都做同样的事情,最终会通过

(function() { 
    //... your code containing an alert 
})(); 

而且给你提醒,如果你想要的是调用警报,您可以对额外功能的语句忘记和回电,只是有

function buildTicket(allRides, passRides, pick){ 
    if(passRides[0]==pick){ 
     var pass = passRides.shift(); 
     alert(); 
    }else { 
     for(var i = 0; i<allRides.length; i++){ 
      if(allRides[i][0] == pick){ 
       alert();          
      } 
     } 
    } 
} 
相关问题