2014-12-06 4 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

Есть ли название для этого синтаксиса? –

+0

Большое спасибо - решает проблему и дает мне причину. Я подозреваю, что могу также сразу вернуть предупреждение без функции и добиться того же результата с помощью вызова buildTicket (parkRides, fastPassQueue, needsRide); –

+0

Существуют некоторые симпатичные аббревиатуры для анонимной версии, которую люди используют для создания локальных областей, то есть в цикле for. IIFE Немедленно вызывается выражение функции и т. Д. – Paul

2

Это должно работать нормально!

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

это тоже хорошо работает;) –

1

Когда вы используете переменный билет(); вы делаете еще один вызов функции, чем в противном случае.

В основном первый вызов buildTicket сам по себе ... buildTicket (parkRides, fastPassQueue, needsRide);

выглядит ...

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

под капотом, и возвращает анонимную функцию, содержащую предупреждение, которое не вызывается еще. Глядя, как ...

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

и так как он не был привязан к переменной она просто сидит там не может быть вызван, потому что у вас нет ссылки на него сейчас. Существует 2 способа решения этой проблемы: 1) вы уже поняли, что назначает анонимную функцию переменной и вызывает функцию с использованием переменной. 2) Чтобы немедленно вызвать возвращаемую функцию, добавив еще один набор парен.

В конце концов, они оба делают то же самое, и в конечном итоге дает вам предупреждение с помощью

(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();          
      } 
     } 
    } 
} 
Смежные вопросы