따옴표와 괄호가 있거나없는 setTimeout의 차이점


240

JavaScript를 배우고 있으며 최근 JavaScript 타이밍 이벤트에 대해 배웠습니다. W3SchoolssetTimeout 에서 알게되었을 때 , 나는 이전 에 하지 않은 이상한 인물을 발견했습니다. 그들은 큰 따옴표를 사용하고 함수를 호출합니다.

예:

setTimeout("alertMsg()", 3000);

JavaScript에서 큰 따옴표와 작은 따옴표는 문자열을 의미합니다.

또한 나는 그렇게 할 수 있음을 보았다.

setTimeout(alertMsg, 3000);

괄호를 사용하면 괄호없이 참조됩니다. 따옴표와 괄호를 사용하면 미쳤어.

누군가이 세 가지 사용 방법의 차이점을 나에게 설명 할 수 있다면 기쁠 것입니다 setTimeout.

괄호로 :

setTimeout("alertMsg()", 3000);

따옴표와 괄호없이 :

setTimeout(alertMsg, 3000);

그리고 세 번째는 따옴표 만 사용합니다.

setTimeout("alertMsg", 3000);

NB : 더 좋은 setTimeout참조 소스는 MDN 입니다.


5
@Jefffrey w3fools 웹 사이트는 내용이 잘못되었다고 말하지 않으며, 구식이며 최신 항목이 누락되었을 수 있습니다. 핵심 내용에 대한 참조로 사용하거나 배우는 것이 좋습니다. 나는 그들이 w3의 일부인 것처럼 보이는 방식으로 좌절감을 느끼는 사람들을 이해할 수 있지만, 그것은 내용을 방해하지 않습니다. 멍청한 놈들에게 명확한 예를 통해 멋지게 정리하고 읽기 쉽습니다.
Matthew

14
@Matthew "W3Schools가 부정확 한 정보로 커뮤니티를 해치고 있다고 생각합니다." -처음 세 줄 내.
구두

1
@Jefffrey 네, 저것을 보았습니다. 그러나 "W3Schools is trouble"섹션에서 그들이 싫어하는 것을 설명하는 곳에서 아래로 내려갑니다. 세 가지 이유 중 어느 것도 부정확 한 정보와 관련이 없습니다. 실제로 "틀린"항목은 하나도 없습니다. 불만 사항은 w3와 관련이 없다고 명시 적으로 말하지 않고 인식 할 수없는 인증에 대한 비용을 청구하며 새로운 컨텐츠 (예 : html 5)로 빠르게 업데이트되지 않는다는 것입니다.
Matthew

10
@Matthew, Javascript, SQL 또는 PHP와 같은 섬세한 언어로 된 오래된 정보 mysql_는 SO 질문 스트림이 단지 예가 되는 오래되고 잠재적으로 위험한 기술 (예 : PHP 확장) 을 고수하는 많은 프로그래머를 안내 합니다. IIRC는 SQL 섹션에도 매우 미묘한 실수가 있었지만 웹 사이트를 마지막으로 방문한 지 거의 1 년이 지났으며 많은 부분이 수정 될 수 있습니다. 그리고 위의 모든 것이 완벽하더라도 인증서 사기로 사람들을 속이려고 시도하는 웹 사이트를 계속 홍보하지는 않을 것입니다.
신발

4
그늘진 인증은 제쳐두고 괜찮은 참고 자료이며 그것을 비난하는 것은 SO의 모든 점에 역효과를 낳습니다.
worc

답변:


382

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()하는 스크립트로 실행하는 문자열을 임의적이고 잠재적으로 유해한 스크립트 실행이 가능하게를.


함수 이름 만 사용하는 경우 함수가 복사되므로 첫 번째 예제에서 setTumeout foo (함수) 패스 참조가 함수가 기댄 함수가 복사되었다고 말하는 이유는 무엇입니까? 그리고 평가 부탁드립니다.
user1316123

41
@ user1316123 기능은 복사되지 않습니다. 객체 및 배열과 동일합니다. 그것들은 참조전달됩니다 . w3schools 읽기를 중단해야합니다. 그들은 선보다 더 많은 해를 끼치고 있습니다
Joseph

4
@JosephtheDreamer 함수 객체입니다. "함수 이름"과 "함수를 나타내는 변수"는 같습니다 . 또한 매개 변수를 setTimeout에 직접 전달할 수 있습니다 (대신 말했듯이 람다를 감쌀 필요가 없습니다. 또한 사용자가 스크립트를 실행할 수있게하는 것이 아닙니다 (항상 항상 수행 할 수 있음)) 다른 사용자 로부터 입력을 받고이를 스크립트로 실행 하는 것입니다 사용자는 항상 콘솔을 열고 임의의 JavaScript를 실행할 수 있습니다
Benjamin Gruenbaum

@ BenjaminGruenbaum 나는 두 번째 문장에 거의 동일한 의견을하려고했다. 웃음 :)
ErikE

2
setTimeout이 제대로 작동하려면 함수를 사용해야한다는 것을 알지 못했습니다. 정리해 주셔서 감사합니다.
Matt Dell

3

작성한 setTimeout 함수가 실행되고 있지 않다고 생각합니다. jquery를 사용하는 경우 다음을 수행하여 올바르게 실행되도록 할 수 있습니다.

    function alertMsg() {
      //your func
    }

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

난 당신을 생각하지만 링크 w3schools.com/js/js_timing.asp somting else
user1316123

브래킷을 사용할 때 올바르게 이해하면 setTimeout 메서드가 포함 된 함수 만 참조 할 수 있기 때문에 로컬 범위에서만 대괄호에서만 사용할 수 있습니까?
user1316123

2

요셉에게 전적으로 동의하십시오.

이것을 테스트하는 바이올린은 다음과 같습니다. http://jsfiddle.net/nicocube/63s2s/

바이올린의 맥락에서 함수가 전역 범위에 정의되어 있지 않기 때문에 문자열 인수가 작동하지 않습니다.


w3schools.com/js/js_timing.asp 링크를 입력 할 수 있다면 Joseph이 위험하다고 말하지만 링크를 입력하면 작동합니다
user1316123

얘들 아 봐주세요 : quirksmode.org/js/this.html 이 링크는 func를 복사 할 수 있다고 말합니다
user1316123

예, 함수는 JS의 객체이기 때문에 가능합니다. eval의 문제점은 전역 컨텍스트에서 평가되고 바이올린으로 발생하는 로컬 컨텍스트를 얻지 못한다는 것입니다.
Nicocube

평가하시기 바랍니다.
user1316123


1

함수의 첫 번째 매개 변수로 문자열을 전달하는 경우 실제로 발생하는 상황

setTimeout ( 'string', number)

실행 시간 ( number밀리 초가 지난 후) 일 때 평가 된 첫 번째 매개 변수의 값입니다 . 기본적으로

setTimeout ( eval('string'), number)

이것은

타이머가 만료 될 때 컴파일되고 실행되는 함수 대신 문자열을 포함 할 수있는 대체 구문입니다. eval ()을 보안 상 위험하게 만드는 것과 같은 이유로이 구문은 권장되지 않습니다.

따라서 귀하가 참조하는 샘플은 좋은 샘플이 아니며 다른 컨텍스트 또는 단순한 오타가 제공 될 수 있습니다.

이런 식으로 호출하면 setTimeout(something, number)첫 번째 매개 변수는 문자열이 아니라라는 이름의 포인터 something입니다. 그리고 다시 something문자열 이면 평가됩니다. 그러나 기능이면 기능이 실행됩니다. jsbin 샘플


0
    ##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.

-1

괄호로 :

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);

위의 예에서 첫 번째 alertMsg2 () 함수 호출 즉시 (우리는 4S를 제한하지만 4A는 기다리지 않습니다) 그 후 alertMsg1 () (2 초 동안 대기) 다음에 alertMsg4 () (8 초 동안 대기) 그러나 alertMsg3 ()은 파티없이 따옴표 안에 배치하므로 문자열로 취급되므로 작동하지 않습니다.


질문자가 묻는 시나리오를 보여 주지만 실제로 질문에 대답하지는 않습니다. 이것이 기존의 6 살짜리 답변 보다 더 많은 것을 보지 못했습니다 .
Stephen P
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.