Разница между setTimeout с кавычками и круглыми скобками и без них

Я изучаю JavaScript и недавно узнал о событиях JavaScript. Когда я узнал о setTimeout в W3Schools, я заметил странную фигуру, с которой раньше не сталкивался. Они используют двойные кавычки и затем вызывают функцию.

Пример:

setTimeout("alertMsg()", 3000);

Я знаю, что двойные и одинарные кавычки в JavaScript означают строку.

Также я увидел, что могу сделать то же самое так:

setTimeout(alertMsg, 3000);

С круглыми скобками - это ссылка, без круглых - его скопированная. Когда я использую цитаты и скобки, это становится сумасшедшим.

Я буду рад, если кто-нибудь сможет объяснить мне разницу между этими тремя способами использования setTimeout:

С круглыми скобками:

setTimeout("alertMsg()", 3000);

Без кавычек и скобок:

setTimeout(alertMsg, 3000);

И третий использует только кавычки:

setTimeout("alertMsg", 3000);

NB. Лучшим источником для ссылки на setTimeout будет MDN.

Ответ 1

Использование setInterval или setTimeout

Вы должны передать ссылку на функцию в качестве первого аргумента для setTimeout или setInterval. Эта ссылка может быть в форме:

  • Анонимная функция

    setTimeout(function(){/* Look mah! No name! */},2000);
    
  • Имя существующей функции

    function foo(){...}
    
    setTimeout(foo, 2000);
    
  • Переменная, которая указывает на существующую функцию

    var foo = function(){...};
    
    setTimeout(foo, 2000);
    

    Обратите внимание, что я установил "переменную в функции" отдельно от "имени функции".Не очевидно, что переменные и имена функций занимают одно и то же пространство имен и могут перекрывать друг друга.

Передача аргументов

Чтобы вызвать функцию и передать параметры, вы можете вызвать функцию внутри обратного вызова, назначенного таймеру:

setTimeout(function(){
  foo(arg1, arg2, ...argN);
}, 1000);

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

setTimeout(foo, 2000, arg1, arg2, ...argN);

Контекст обратного вызова

По умолчанию контекст обратного вызова (значение this внутри функции, вызываемой таймером) при выполнении является window глобального объекта. Если вы хотите изменить его, используйте bind.

setTimeout(function(){
  this === YOUR_CONTEXT; // true
}.bind(YOUR_CONTEXT), 2000);

Безопасность

Хотя это возможно, вы не должны передавать строку в setTimeout или setInterval. Передача строки заставляет setTimeout() или setInterval() использовать функциональность, аналогичную eval() которая выполняет строки как сценарии, делая возможным произвольное и потенциально опасное выполнение сценариев.

Ответ 2

Я думаю, что функция setTimeout, которую вы пишете, не запускается. если вы используете jquery, вы можете сделать это правильно, выполнив следующее:

    function alertMsg() {
      //your func
    }

    $(document).ready(function() {
       setTimeout(alertMsg,3000); 
       // the function you called by setTimeout must not be a string.
    });

Ответ 3

Полностью согласен с Джозефом.

Вот скрипка, чтобы проверить это: http://jsfiddle.net/nicocube/63s2s/

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

Ответ 4

Что происходит в действительности, если вы передаете строку в качестве первого параметра функции

setTimeout ('string', number)

значение первого полученного параметра, вычисляемого в момент запуска (по истечении number миллисекунд). В основном это равно

setTimeout (eval('string'), number)

Это

альтернативный синтаксис, который позволяет вам включать строку вместо функции, которая компилируется и выполняется по истечении таймера. Этот синтаксис не рекомендуется по тем же причинам, которые делают использование eval() угрозой безопасности.

Таким образом, образцы, на которые вы ссылаетесь, не являются хорошими образцами и могут быть приведены в другом контексте или просто опечатка.

Если вы вызываете как этот setTimeout(something, number), первый параметр не строка, а указатель на что- something что называется something. И снова, если something является строкой - тогда это будет оценено. Но если это функция, то функция будет выполнена. образец jsbin

Ответ 5

    ##If i want to wait for some response from server or any action we use setTimeOut.

    functionOne =function(){
    console.info("First");

    setTimeout(()=>{
    console.info("After timeOut 1");
    },5000);
    console.info("only setTimeOut() inside code waiting..");
    }

    functionTwo =function(){
    console.info("second");
    }
    functionOne();
    functionTwo();

## So here console.info("After timeOut 1"); will be executed after time elapsed.
Output:
******************************************************************************* 
First
only setTimeOut() inside code waiting..
second
undefined
After timeOut 1  // executed after time elapsed.

Ответ 6

С круглыми скобками:

setTimeout("alertMsg()", 3000); // It work, here it treat as a function

Без кавычек и скобок:

setTimeout(alertMsg, 3000); // It also work, here it treat as a function

И третий использует только кавычки:

setTimeout("alertMsg", 3000); // It not work, here it treat as a string

function alertMsg1() {
        alert("message 1");
    }
    function alertMsg2() {
        alert("message 2");
    }
    function alertMsg3() {
        alert("message 3");
    }
    function alertMsg4() {
        alert("message 4");
    }

    // this work after 2 second
    setTimeout(alertMsg1, 2000);

    // This work immediately
    setTimeout(alertMsg2(), 4000);

    // this fail
    setTimeout('alertMsg3', 6000);

    // this work after 8second
    setTimeout('alertMsg4()', 8000);