ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CS Study] 스코프란 & 호이스팅이란 무엇일까???
    네트워크/CS Study 2023. 6. 19. 17:19

    스코프란 무엇인가?  

     변수의 유효범위를 말하는 것이고 이 유효범위의 이해를 위해서 간단한 예제 코드를 보면서 알아보자.

    let greeting = 'Hello';
    
    function greetSomeone(){
        let firstName = 'KJ';
        return greeting + ' ' + firstName;
    }
    
    console.log(greetSomeone()); // Hello KJ	하위스코프는 상위스코프에 접근이 가능
    // console.log(firstName); // 접근 불가능   상위스코프는 하위스코프에 접근 불가능

    전역스코프 && 지역스코프 

    전역스코프는 가장 바깥에 있는 스코프를 가르키고 지역스코프는 전역스코프 외 스코프를 가리키는 말이다.

     


    스코프체인

    이러한 전역, 지역 스코프에 대한 개념이 함수와 맞물리면서 나타난 것이 스코프체인이란 말이야~

    위 보기와 같이 중첩함수에서 스코프가 단방향성(상위스코프는 하위스코프의 정보를 가지고 놀 수 없음)을 가지게 되고 이로 인해 나올 수 있는 결과를 잘 예상 할 수 있어야 하겠다.


    그래서 왜 알아야 하나? 

    스코프는 스코프 체인이 만들어짐에 따라서 스코프가 다르다면 같은 이름의 변수선언을 가능하게 해준다.

    이게 가능 한 이유는 스코프를 나눔으로써 변수이름의 충돌을 방지해주기 때문이고 이때 동일한 이름의 변수(서로다른 스코프의)는 우선순위를 가지게 되는데 전역스코프 < 지역스코프 이다.

    let name = "KJ"; // 전역 변수
    
    function showName(){
        let name = "SJ"; // 지역 변수
        console.log(name);
    }
    
    console.log(name); // KJ
    showName(); // SJ
    console.log(name); // KJ

    위 글을 보게 되면 지역에서의 호출에서는 전역변수의 "KJ" 호출되는데 지역변수로 선언된 showName 함수 내에서는 지역변수가 우선순위를 가지게 되어 showName()를 호출했을 떄 지역변수인 "SJ"가 호출 된다.

    이 때 쉐도잉이라고 불리는 현상이 나타나는데 같은 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 가려지는 현상을 말한다.

    추가 주의 사항

    지역 스코프에서 선언을 하지 않고 할당을 한다? 그럼 전역변수에 재할당이 되는 것이다 그러면 스코프를 쓰는 이유가 없지요 변수충돌이 생기기때문에~ 조심히 해야겠군

     

     


    함수레벨 스코프와 블록레벨 스코프  뭔데?

    함수 레벨 스코프란 함수 내에서 선언 된 변수는 함수 내에서만 유효하고 함수 외부에서는 참조 할 수 없다는 것이고 함수 내부에서 선언한 변수는 지역변수이며 와부에서 선언한 변수는 모두~~ 전역변수이다.

    대표적으로 var 선언한 것이 함수레벨 스코프인데 이 애는 준내 흔들린다 전역스코프에서 20이란 값을 선언 및 할당했더라 하더라도 for문에서 동일한 변수명인 i를 사용해버린다면?? 대참사로 전역스코프에서 변수를 호출했을 때 for문에서 마지막에 할당 받은 값이 찍히게 된다 .. 세상에.... 이러니 블록레벨 스코프를 써야겠지? var 쓰지말란 소리 알겠지?

     

    블록레벨 스코프란 {}안에서 실행 된 변수는 {} 안에서만 유효하다 {} 밖에서는 참조 못한다 즉 {} 안에껀 지역변수다

    ex) 함수, if, for, while, 등등... let 선언도 블록레벨임


    렉시컬스코프와 다이나믹스코프???

     

    일단 JS는 렉시컬 스코프를 따른다 함수 선언 위치에 따라 결정되는 상위 스코프를 말하는데 간단하게 실행되는 함수를 선언했을 떄 감싸고 있는 스코프가 누구인지가 중요하다. 근데 이거 callstack개념이랑 맞물려서 생각하니까 더 잘생각이 되는데 이게 맞는건지 모르겠다 나중에 물어봐야지...  

    var num = 1; // Lexical Scope에서 가장 가까운 변수
    function changePrint (){
    	console.log(num);
    }
    
    function change (){
      var name = 100;
      changePrint();
    }
    
    change();

     

     

    다이나믹스코프는 JS문법으로는 표현 못한다 다만 만약에 있다면 호출이 어느스코프에서 일어나는가에 따라서 전역변수가 결정이 된다. 

     

     


    var 이녀석은 무엇인가???

     

    ES5에서까지는 변수를 선언할 수 있는 유일한 녀석이였다.

    이 var 라는 키워드가 알짱거리는 이유는 var 키워드를 썼을 때 나타나는 안좋은 상황과 그로 인해 ES6문법에서 새롭게 나온 let , const 를 설명하기 전에 필요한 개념이 있기 때문이다.

    var foo = 123; // 전역 변수
    
    console.log(foo); // 123
    
    {
      var foo = 456; // 전역 변수
    }
    
    console.log(foo); // 456

    이 요상한 녀석을 보라 스코프(여기서는 블록)에 상관없이 자기멋대로 변수 값이 바뀌어 버린다. 이 재선언을 해도 에러가 발생하지 않는다는게 너무나 큰 문제점이다. 만약 선언 없이(let const) 변수를 할당한다면 var망태기할아범이 와서 선언을 해버릴거야... 그러니 변수를 선언 할 때 있어서 const 와 let을썼는지 조심하자

    또한 호이스팅 과정에서 선언시 초기화를 해버리기 때문에 값을 할당하지 않았을 때 refenece error 가 아닌 undefined로써 값이 없다는 이상한 소리를 한다(그래서 let이랑 const 가 좋아..ㅎ)


     

    호이스팅!

    변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. (변수 함수 선언이 맨위로 끌어올려진다)

    호이스팅이 발생하는 이유는 아래의 과정을 거치면서 자바스크립트 엔진은 코드가 실행 전에 실행 컨텍스트에 등록된 변수, 객체에 접근 할 수 있다. 이과정에서 var는 선언과 초기화를 같이 해서 문제다. 

    선언 단계 변수를 실행 컨텍스트(실행 코드에 제공할 정보 객체)의 변수 객체에 등록한다.
    초기화 단계 변수 객체에 등록된 변수를 위한 메모리 공간을 확보한다. (이때, undefined로 초기화됨)
    메모리가 할당되면 메모리 참조를 통해 변수에 접근할 수 있다.
    할당 단계 사용자가 정의한 값을 변수에 할당해준다

     

    호이스팅에서 중요하게 바라보아야 할 개념은 var는 호이스팅을 하고 let과 const는 하지않는다는 생각을 하지 않게끔 개념을 잡는것이 중요하다 

    간단하게 let const를 설명하자면 재할당이 가능하지만 선언을 중복으로 할 수 없다면 let 재할당 중복선언 둘다 못하면 const 라고 생각하고 밑의 예제를 참고해보자

    let a; // 전역 변수
    {
      console.log(a); // ReferenceError
      let a = 2; // 지역 변수
    }

    재할당이 불가능한 const는 제쳐두고 let이 호이스팅을 한다는 증거를 보여주겠다.

    전역변수로 처음 선언된 a와 다른 스코프에 존재하는 출력문과 다른스코프에서 선언을 하고 있는 a 의 모습이  보일것이다. 만약 let이 호이스팅이 되지않는다는 가정을 한다면 출력문에서 a를 불렀을 때 현재 스코프에 존재하지 않으므로 상위 스코프로 가서 a를 참조해야한다(스코프 체인) 근데 여기서 보면 상위스코프로 가기는 커녕 응~없어 라는 듯이 ref error를 내버린다. 이는 즉! 호출문의 스코프 내에서 초기화가 이루어지기 전상태인 a가 존재한다는 이야기가 된다. 이러한 모습을 보았을 때 let과 const는 참조할 메모리가 없는것이다.(호이스팅이 됩니다) 

     

    마지막으로 함수의 경우 함수선언문의 경우에는 선언 & 초기화 & 할당이 동시에 일어나므로 당연하게 호이스팅이 되함수 표현식의 경우 var를 사용한다면 초기화까지 되고 let 이나 const 를 사용하면 선언까지만 된다. 그리고 화살표함수는 호이스팅 되지 않는다. 그러니 화살표 함수를 사용할때는 선언과 호출의 순서를 주의해서 사용하자~

     

     

     

     

     

    참고자료

     

    https://nayoungkim00.tistory.com/53

     

    자바스크립트의 Scope 스코프 (렉시컬 환경, 호이스팅, var, let과 const)

    목차 1. 스코프란? 1-1. 렉시컬 환경 2. 스코프의 종류 2-1. 스코프 체인 2-2. 함수 레벨 스코프 3. 전역 변수 3-1. 문제점 3-2. 해결방법 4. let과 const 4-1. 호이스팅 4-2. 무엇을 사용해야 할까? 1. 스코프란?

    nayoungkim00.tistory.com

    https://mong-blog.tistory.com/entry/JS-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85hoisting

    '네트워크 > CS Study' 카테고리의 다른 글

    [항해99 WIL] ES5 VS ES6  (0) 2023.06.21
    [CS Study] Closure  (0) 2023.06.21
    [CS Study] MVVM && FLUX  (0) 2023.06.20
    [CS Study] fetch / axios && API란 무엇일까?  (1) 2023.06.18
    async /await 에 대하여  (2) 2023.06.14

    댓글

Designed by Tistory.