ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Javascript] 자바스크립트 블록, 함수 스코프, 클로저 문제
    Javascript 2023. 5. 23. 17:14
    반응형

    var 와 let의 차이 이해하기

    let

    for(let i = 0; i < 6; i++){
                setTimeout(() => {
                    drawBall(winBalls[i], $result);
                }, (i + 1) * 1000);  //(i + 1)초 뒤에 추가
            }

    var

    for(var i = 0; i < 6; i++){
                setTimeout(() => {
                    drawBall(winBalls[i], $result);
                }, (i + 1) * 1000);  //(i + 1)초 뒤에 추가
            }

     

    콘솔로 찍어보면

     

    let

    var

    var 사용 시 $result = 6이 나오는 이유

    • 변수는 스코프(scope, 범위)를 가진다.
    • 스코프: 변수의 접근 가능한 범위
    • var: 함수 스코프를 가짐, 변수를 함수 내부에서 선언 후 함수 밖으로 빠져나오면 해당 변수에 접근 불가
    • let: 블록 스코프를 가짐, 변수를 블록(함수, if, while...) 내부에서 선언 후 블록 밖으로 빠져나오면 해당 변수에 접근 불가
    if(1){
        var a = 3;
        let b = 3;
    }
    console.log(a);
    console.log(b);

    스코프

    if문 블록 외부에서 var로 선언된 변수는 접근이 가능하지만 let으로 선언된 변수는 접근이 불가하다.

     

    for문 특성

    for(var i = 0; i < 6; i++){}
    console.log(i);
    
    //출력: 6

    1. i가 5인 상태에서 i++

    2. i = 6이 된다.

    3. 조건문이 false이므로 for문에서 빠져나온다.

    4. i값을 출력하면 6이 나온다.

     

    클로저

    var

    • 파란색으로 선택된 부분(setTImeout의 콜백 함수 내부)은 비동기이므로 실제 코드와 다른 시점에 실행된다.
    • 반복문은 동기이므로 코드가 나오는 시점에 바로 실행된다.
    • 따라서 1초 후에 파란색 부분이 실행될 때, i는 반복문을 끝까지 돌아 이미 6이 되어 있다.
    • 즉, winBalls[6] = undefined가 된다.

     

    ■ let

    • let은 블록 스코프이므로, i 값이 하나의 블록마다 내부에서 고정된다.
    • setTimeout 콜백 함수 내부 i 값 ==  setTimeout 호출 시의 i 값

    var을 사용할 시 발생하는 문제 해결 방안 (클로저를 사용해 문제 해결)

    클로저: 함수와 함수 외부에 있는 변수 간의 관계

     for(var i = 0; i < winBalls.length; i++){
                (function(j) {
                    setTimeout(() => {
                        drawBall(winBalls[i], $result);
                    }, (i + 1) * 1000);  //(i + 1)초 뒤에 추가
                })(i);
            }

    함수를 바로 호출해, 함수 내부 j를 사용하여 문제를 해결한다.

    • 함수를 소괄호로 감싼 뒤, 소괄호 뒤에 ()를 붙여준다.
    • j: 함수의 매개변수, 함수 안에 갇힌다.
    • i: 함수의 인수
    • i는 j로 전달된다.
    • ☞ 함수를 만들어 인수를 넣고 호출해주는 형태이다.

     

    알아두기

    함수 스코프를 가진 변수(var) 비동기 함수(setTime 등)가 만나면 클로저 문제가 발생한다.

     

    출처

    https://tinyurl.com/ytnfzjmx

     

    반응형

    댓글

Designed by Tistory.