1

code_0:вызова функции Javascript с/без скобок

(вызов foo без скобок)

function foo(){ 
    console.log('hello world'); 
} 

setTimeout(foo, 2000); 

Это как code_0 было выполнено:

start -> wait for 2 seconds -> 'hello world' displayed -> end 

code_1:

(вызов foo с круглыми скобками)

function foo(){ 
    console.log('hello world'); 
} 

setTimeout(foo(), 2000); 

И это, как code_1 была выполнена:

start -> 'hello world' displayed immediately -> wait for 2 seconds -> end 

Почему программа будет выполнять настолько по-разному, когда я назвал функцию со скобками? Каков основной механизм?

Извините, если этот вопрос слишком тривиален. Но я не мог найти объяснения в любом учебнике javascript для начинающих.

ответ

3

setTimeout(foo, 2000) передает функции foo и номер 2000 в качестве аргументов setTimeout. setTimeout(foo(), 2000) вызывает foo и передает его возвращаемое значение и номер 2000 - setTimeout.

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

В более простом примере, просто зарегистрировать ее:

function foo() { 
    return 5; 
} 

console.log(foo); // console.log is passed a function and prints [Function] 

console.log(foo()); // foo() is called and returns 5; console.log is passed 5 
        // and prints 5 
+0

Так что, если функция foo имеет аргумент. Вроде: функция foo (arg) { console.log ('hello' + arg); } Как использовать setTimeout для foo, но также передать параметр 'world' для foo? – delsin

+1

@Delsin: Вы можете передать функцию, которая вызывает эту функцию по очереди. Например: 'setTimeout (function() {foo ('some argument');}, 2000);'. Существует также встроенная функция для функций 'bind', которая устанавливает' this' и некоторые ведущие аргументы: 'setTimeout (foo.bind (null, 'some argument'), 2000);' – Ryan

+1

@ RyanO'Hara - Сделать это немного сложным, не так ли? После аргумента задержки любые дополнительные аргументы, которые вы передаете, отправляются функции. Пример: 'setTimeout (foo, 2000, myArg1, myArg2, myArg3);' Почему бы просто не сделать это? –

2

В первом фрагменте кода, функция foo настоящее время передается в тайм-аут. Это означает, что foo вызывается через 2 секунды, когда истекает время ожидания.

Во втором фрагменте кода функция foo находится в состоянии , вызывая решение о переходе на таймаут. Таким образом, foo вызывается до истечения времени ожидания. Поскольку foo() ничего не возвращает, ничего не происходит, когда истекает время ожидания.

2

В своем вопросе, foo является

function foo(){ 
    console.log('hello world'); 
} 

тогда foo() является

console.log(hello world)

SetTimeout() метод вызывает функцию или вычисляет выражение после определенного числа миллисекунд, и эта функция должна быть первым параметром для него, в вашем первом случае вы передаете функцию, поэтому поведение выполняется ex и во втором случае вы проходите console.log(...), который не является функцией, поэтому он сначала выполняет foo() и печатает на консоли hello world, затем ждет 2 секунды и ничего не делает и, таким образом, демонстрирует странное поведение.

См

typeof foo; // is function

typeof foo(); // prints hello world in console first and then says undefined.

2

Основное различие между foo и foo() заключается в следующем:

function foo() { 
    alert("bar"); 
    return "baz"; 
} 

console.log(foo); // gives "function" 
console.log(foo()); // gives "baz" 

foo является ссылкой на теле функции самого whil e foo()выполняет функцию. Таким образом,

setTimeout(foo(), 2000); 

передает возвращаемое значение («БАЗ») к функции setTimeout (что приведет к ошибке). setTimeout ожидает, что в качестве первого аргумента будет выполняться функция «executable», поэтому вам нужно передать ссылку на существующую функцию.

1

Точка путаницы здесь является то, что вы не понимая, что с помощью foo без скобок не вызова функции ... это только ссылаться на него.

foo - ссылка на функцию. Чтобы вызвать функцию (т.е. фактически выполнить ее код), вы ссылаетесь на нее с круглыми скобками в конце (например, foo()). В практическом смысле это означает:

// references the function itself 
// ...you could call one() now and it would run the function foo 
var one = foo; 

// runs/calls the function, and var two will then be whatever foo returns 
var two = foo(); 

Итак, в первом примере вы НЕ НАЗЫВАЕТ функцию. Вы передаете функцию foo на номер setTimeout. setTimeout будет затем позвонить это после задержки.

Во втором примере вы под названием Foo немедленно передается какой бы то ни foo возвращается к SetTimeout (который SetTimeout не мог ничего с делать, потому что возвращаемое значение, вероятно, не была еще одна функция). Таким образом, ваша функция была выполнена немедленно, а затем ничего не произошло (за исключением, вероятно, некоторых ошибок) после того, как setTimeout было выполнено с задержкой.

Смежные вопросы