ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스코프(Scope)
    frontend/javascript&web 2022. 2. 9. 19:47

    Concept By 스코프(Concept By Scope)

     

    스코프(Scope)

    • 현재 접근할 수 있는 변수들의 범위

     

    쉽게 말해 실행 컨텍스트에서 접근 가능한 변수라고 생각하면 됩니다. 스코프에는 총 3가지 개념이 있습니다.

    1. 함수 스코프
    2. 렉시컬 스코프
    3. 블록 스코프

     

    우리는 이미 렉시컬 스코프를 클로저에서 만나보았습니다. 사실 함수와 블록 스코프도 이미 호이스팅에서 맛은 보았다고 볼 수 있습니다. 먼저, 함수 스코프를 기반으로 설명해드리겠습니다.

     

    예시

    var ratio = 1.6; // (1)
    function getIncreaseSalary(salary){ // (2)
    	var total = salary * ratio;
    	return total;
    }
    var nextYearMySalary = getIncreaseSalary(10); // (3)
    전역 실행 컨텍스트 전역 메모리
      ratio : 1.6
    getIncreaseSalary :  fn  (2)
    nextYearMySalary : (3)

    위의 코드는 상승된 연봉을 구하는 간단한 예제 코드입니다. 먼저, 전역 메모리 ratio 변수에 1.6이라는 값을 할당하고 getIncreaseSalary라는 이름의 함수에 함수식을 연결해줍니다. 그리고 getIncreaseSalary의 리턴 값을 값을고 가지는 변수를 만들어 줍니다.

    var ratio = 1.6; 
    function getIncreaseSalary(salary){ // (1)
    	var total = salary * ratio; // (2)
    	return total;
    }
    var nextYearMySalary = getIncreaseSalary(10);
    전역 실행 컨텍스트 전역 메모리
    getIncreaseSalary() (1) ratio : 1.6
    getIncreaseSalary :  fn  fn 
    nextYearMySalary :
    함수 실행 컨텍스트 지역 메모리
    total = salary * ratio salary : 10 (1)
    total : (2)

    그 다음 getIncreaseSalary() 함수를 호출하면 실행컨텍스트를 만들고 지역메모리에 매개변수 10이라는 값이 할당됩니다. 그 후 total을 만들고 salary * ratio 값을 할당 받아야 됩니다. ratio값은 함수의 메모리에 없기 때문에 콜스택의 바닥인, 즉 상위 컨텍스트인 전역 컨텍스트를 찾아 봅니다.

    var /**ratio*/ = 1.6; 
    function getIncreaseSalary(salary){ 
    	var total = salary * /**ratio;*/ // (1)
    	return total; // (2)
    }
    var nextYearMySalary = getIncreaseSalary(10);
    전역 실행 컨텍스트 전역 메모리
    getIncreaseSalary() (1) ratio : 1.6
    getIncreaseSalary :  fn  fn nextYearMySalary :
    함수 실행 컨텍스트 지역 메모리
    total = salary * ratio salary : 10 (1)
    total : 16 (2)

    전역 컨텍스트에서 ratio값을 가져와 salary * ratio 연산을 통해 total에 값을 할당하고 그 값을 리턴 합니다.

    var ratio = 1.6; 
    function getIncreaseSalary(salary){ 
    	var total = salary * ratio; 
    	return total;
    }
    var nextYearMySalary = getIncreaseSalary(10); // (1)
    전역 실행 컨텍스트 전역 메모리
      ratio : 1.6
    getIncreaseSalary :  fn 
    nextYearMySalary : 16 (1)

    함수가 종료되면 함수 실행컨텍스트는 사라지게 되며 전역메모리에 값이 들어갑니다. 이제 내부 동작은 어느정도 눈에 들어오시죠?

     

    정리하자면, 스코프는 현재 접근할 수 있는 변수들의 범위를 말합니다. 위에서 본 개념은 함수 스코프라고 할 수 있습니다. 그리고 현재 실행중인 실행컨텍스트에서 변수를 찾을 수 없다면 이전 실행컨텍스트 즉, 상위 컨텍스트(콜스택 하위)로 탐색 범위를 넓히는 것을 우리는 스코프 체인이라고 부릅니다.

     

    DeepDive By 스코프(DeepDive By Scope)

     

    ES6이전에는 변수를 선언할 수 있는 방법은 var 였습니다. var는 함수 스코프를 가지고 있고, 키워드 생략이나 변수 중복 선언, 호이스팅 등 이러한 특성으로 인해서 의도하지 않는 문제를 일으키는 일이 많았고 이를 해결하기 위해서는 스코프를 좁히는 것이 필요했습니다. ES6에서 이러한 var키워드의 단점을 보완하기 위하여 let과 const 키워드가 나오게 되었고 이는 여타 언어들과 같이 블록 스코프를 지원하게 되었습니다.

     

    예시

    함수스코프

    var simple = "류호진";
    {
    	var simple = "테스터";
    	console.log(simple); //테스터
    }
    console.log(simple); //테스터

    블록스코프

    let simple = "류호진";
    {
    	let simple = "테스터";
    	console.log(simple); //테스터
    }
    console.log(simple); //류호진

    간단합니다 var는 함수 스코프를 가지고 있기 때문에 블록 안이지만 변수가 덮어져 둘다 테스터 라는 결과값을 출력하게 됩니다. 마지막으로 스코프체인의 개념을 확실히 하기 위해 하나의 예시를 보고 가겠습니다

     

    예시

    function findFE(){ // (1)
    	var feDeveloper = "류호진";
    	function bnk(){
    		function it(){
    			console.log(feDeveloper);
    		}
    		it();
    	}
    	bnk();
    }
    var who = findFE(); // (2)
    전역 실행 컨텍스트 전역 메모리
      findFE :  fn  (1)
    who :

    먼저 findFE 함수를 전역 메모리에 등록하고 findFE의 리턴값을 값으로 가지는 who변수를 만들어 메모리에 등록합니다.

    function findFE(){
    	var feDeveloper = "류호진";
    	function bnk(){ // (2)
    		function it(){
    			console.log(feDeveloper);
    		}
    		it();
    	}
    	bnk();
    }
    var who = findFE(); // (1)
    전역 실행 컨텍스트 전역 메모리
    findFE (1) findFE :  fn 
    who :
    함수 실행 컨텍스트 지역 메모리
      feDeveloper : 류호진 (2)
    bnk :  fn  (2)

    그 다음 findFE 함수를 실행시키면 함수 실행컨텍스트가 만들어지고 지역메모리에는 류호진을 값으로 가지는 feDeveloper변수와 bnk함수가 등록됩니다.

    function findFE(){
    	var feDeveloper = "류호진";
    	function bnk(){
    		function it(){ // (2)
    			console.log(feDeveloper);
    		}
    		it();
    	}
    	bnk(); // (1)
    }
    var who = findFE();
    전역 실행 컨텍스트 전역 메모리
    findFE() findFE :  fn 
    who :
    함수 실행 컨텍스트 지역 메모리
    bnk() (1) feDeveloper : 류호진
    bnk :  fn  
       
      it :   fn  (2)

    bnk 함수를 실행시키면 함수 실행컨텍스트 내에 다시 bnk 함수의 실행 컨텍스트가 등록이 됩니다. 그 후 it 함수가 지역메모리에 등록이 됩니다.

    function findFE(){
    	var feDeveloper = "류호진";
    	function bnk(){
    		function it(){ // (1)
    			console.log(feDeveloper); // (2)
    		}
    		it();
    	}
    	bnk();
    }
    var who = findFE();
    전역 실행 컨텍스트 전역 메모리
    findFE() findFE :  fn 
    who :
    함수 실행 컨텍스트 지역 메모리
    bnk() feDeveloper : 류호진
    bnk :  fn  
       
    it() it :   fn  
       
    console.log(feDeveloper)  

    마지막으로 it 함수를 실행시키면 함수 실행컨텍스트가 실행되는데 실행시킬 코드인 console.log(feDeveloper)의 변수 feDeveloper를 가장 먼저 지역메모리에서 찾게 됩니다. 그 후 상위 컨텍스트의 지역메모리에서 쭉쭉 탐색을 하다가 findFe() 내부의 feDeveloper변수를 가져다가 사용합니다. 이게 스코프 체이닝입니다. 이후엔 함수가 하나씩 종료되고 함수 실행컨텍스트가 사라지고 콜스택이 하나씩 pop()되는 것은 이제 그림으로 안보여 드려도 다음이 어느정도 예측되시죠?

     

    이상으로 스코프에 대한 간단한 설명을 마쳤습니다. 스코프 뿐만 아니라 전체적인 코어 자바스크립트는 유기적으로 이어져있어 가면 갈수록 이해가 쉬워지는 것을 느끼실 수 있으실 겁니다. 다음장에서는 조금 갱니적으로 짜증나는.. 이벤트 루프에 대해서 알아보겠습니다.

     

    참고 : NHN FRONT-END CONFERENCE

             JAVASCIPRT CONFERENCE

    반응형

    'frontend > javascript&web' 카테고리의 다른 글

    프로토타입(Prototype)  (0) 2022.02.16
    이벤트 루프(Event Loop)  (1) 2022.02.15
    호이스팅(Hoisting)과 클로저(Closure)  (0) 2022.02.08
    콜 스택(Call Stack)  (0) 2022.02.06
    실행 컨텍스트(Excution Context)  (0) 2022.02.04

    댓글

Designed by Tistory.