ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바스크립트 스코프
    자바스크립트,제이쿼리 2019. 10. 13. 01:46

    정적 스코프와 동적 스코프

    정적 스코프는 어떤 변수가 함수 스코프 안에 있는지 함수를 정의할 때 알 수 있다는 뜻이다.

    호출할 때 알 수 있다는 것이 아니다.

            var x=3;
    
            function f() {
                console.log(x);
                console.log(y);
            }
    
            function j() {
            var y=2;
            f();
            }
    
            j();

    변수 x는 함수 f를 정의할 떄 존재하지만, y는 그렇지 ㅇ낳습니다. y는 다른 함수에 존재합니다. 다른 함수에서 y를 선언하고 그 스코프에서 f를 호출하더라도, f를 호출하면 x는 그 바디안의 스코프에 있지만 y는 그렇지 않습니다. 이것이 정적 스코프입니다. 함수 f는 자신이 정의 될때 접근할 수 있었던 식별자에 접근할 수 지만, 호출할 때 스코프에 있는 식별자에 접근할 수가 없습니다. 자바스크립트의 정적 스코프는 전역 스코프와 블록 스코프, 함수 스코프에 적용됩니다.

     

    함수, 클로저, 정적 스코프

    모든 함수를 전역에서 정의하고 함수 안에서 전역 스코프를 참조하지 않도록 신경 쓰는 전통적 프로그램에서는 함수가 어떤 스코프에 접근할 수 있는지 생각할 필요도 없습니다.

    하지만 최신 자바스크립트에서는 함수가 필요한 곳에서 즉석으로 정의할 때가 많습니다. 함수를 변수가 객체 프로퍼티에 할당하고, 배열에 추가하고, 다른 함수에 전달하고, 함수가 함수를 반환하고, 심지어 이름조차 없을 때도 잦습니다.

    함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 경우가 많습니다. 이런 것을 보통 클로저라고 부릅니다. 스코프를 함수 주변으로 좁히는 것이라고 생각해도 됩니다.

     

    즉시 호출하는 함수 표현식

    함수 표현식을 사용하면 즉시 호출하는 함수 표현식이란 것을 만들 수 있습니다. IIFE는 함수를 선언하고 즉시 실행합니다. 

        (function() {
            // IIFE 바디
        })();
    
        var message = (function() {
            var secret = "I'm a secret!";
            return "The secret is " +secret.length+ " characters long.";
        })();
        console.log(message);

    함수 표현식으로 익명 함수를 만들고 그 함수를 즉시 호출합니다. IIFE의 장점은 내부에 있는 것들이 모두 자신만의 스코프를 가지지만, IIFE 자체는 함수이므로 그 스코프 밖으로 무언가를 내보낼 수 있다는 겁니다.

    변수 secret은 IIFE의 스코프 안에서 안전하게 보호되며 외부에서 접근할수 없습니다. IIFE는 함수이므로 무엇이든 반활할 수 있습니다. IIFE에서 배열이나 객체, 함수를 반환하는 경우도 무척 많습니다. 

     

    함수 스코프와 호이스팅

    ES6에서 let을 도입하기 전에는 var를 써서 변수를 선언했고, 이렇게 선언된 변수들은 함수 스코프라 불리는 스코프를 가졌습니다. let으로 변수를 선언하면, 그 변수는 선언하기 전에는 존재하지 않습니다. var로 선언한 변수는 현재 스코프 안이라면 어디서든 사용할 수 있으며, 심지어 선언하기도 전에 사용할 수 있습니다. 아직 선언되지 않은 변수와 값이 undefined인 변수는 다르다는 점을 상기해 봅시다. 아직 선언되지 않은 변수는 에러를 일르키지만, 존재하되 값이 undefined인 변수는 에러를 일으키지 않습니다.

        let var1;
        let var2 = undefined;
        console.log(var1);
        console.log(var2);
        undefinedVar; //ReferenceError : undefinedVar는 정의되지 않았습니다.

     

    let을 쓰면, 변수는 선언하기 전 사용하려 할 떄 에러가 일어납니다.

        x;
        let x = 3; //에러가 일어나서 실행이 멈췄으므로 여기에는 결코 도달할 수 없습니다.

    반면 var로 변수를 선언하면 선언하기 전에도 사용할 수 있습니다.

        x; //undefined
        var x =3;
        console.log(x);

    자바스크립트는 함수나 전연 스코프 전체를 살펴보고 var로 선언한 변수를 맨 위로 끌어올립니다. 여기서 중요한 것은 선언만 끌어올려진다는 것이며, 할당은 끌어올려지지 않는다는 겁니다. 자바스크립트는 위에 코드를 다음과 같이 해석합니다.

    var x; //선언(할당이 아닌)이 끌어올려집니다.
    x; //undefined
    x = 3;
    x; // 3

     

    함수 호이스팅

    var로 선언된 변수와 마찬가지로, 함수 선언도 스코프 맨 위로 끌어올려집니다. 따라서 함수를 선언하기 전에 호출할 수 있습니다.

        f(); // 'f'
        function f() {
            console.log('f');
        }

    변수에 할당한 함수 표현식은 끌어올려지지 않고, 이들은 변수의 스코프 규칙을 그대로 따른다.

        f(); // ReferenceError : f는 정의도지 않았습니다.
        var f = function {
            console.log('f');
        }

     

    출처 - 러닝 자바스크립트

    '자바스크립트,제이쿼리' 카테고리의 다른 글

    자바스크립트 프라미스  (0) 2019.10.16
    자바스크립트 콜백  (0) 2019.10.15
    자바스크립트 객체  (0) 2019.10.07
    자바스크립트 null과 undeifned  (0) 2019.10.07
    자바스크립트 함수  (0) 2019.10.06
Designed by Tistory.