안녕하세요. 숯 같은 개발자 엄탱입니다!
오늘은 유독 컨디션이 좋지 않은 날이었습니다 ㅎㅎ
여러분 컨디션 조절 잘하세요!!
건강도 실력이라고 그러는데, 저는 역시나 아직은 초보자인 것 같습니다.
오늘은 스코프(scope)에 대해서 준비를 해보았습니다.
그런데 MDN 사이트에서만 참고해서 이해하기에는 자료가 부족하여 여러 블로그들을 참고하여 알아보았습니다.
아래는 참고한 사이트 주소들입니다.
https://poiemaweb.com/js-scope#5-비-블록-레벨-스코프non-block-level-scope
https://hanamon.kr/javascript-스코프와-변수선언키워드-차이점/
자 그럼 시작해보겠습니다.
스코프의 정의
스코프(scope)는 사전적 의미로 ‘범위'라는 뜻을 갖고 있습니다.
어떤 범위를 말하는 걸까요?
MDN 사이트에서는 아래와 같이 설명합니다.
MDN 사이트
현재 실행되는 컨텍스트를 말합니다.
여기서 컨텍스트는 값과 표현식이 "표현"되거나 참조될 수 있음을 의미합니다.
만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없습니다.
스코프는 또한 계층적인 구조를 가지기 때문에 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가합니다.
이것을 한마디로 표현을 하고 싶어서 여기저기 찾아봤는데, 결국 의미하는 바는 같은데 한 문장으로 표현한 말들은 다양하더라고요.
그래서 많은 블로거 분들이 표현한 문장들을 아래에 작성해보았습니다.
- 스코프는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙
- 스코프의 정의는 “식별자 접근 규칙에 따른 유효 범위”
- 변수가 영향을 미치는 범위, 변수의 유효 범위, 코드가 유효한 범위
위와 같이 다양한 정의를 확인할 수 있습니다.
제가 생각한 가장 깔끔하고 이해하기 쉬운 정의는 변수가 접근 혹은 참조하는 범위입니다.
스코프의 구분
우선 간단하게 구분을 짓고 자세한 건 하나하나 설명을 드리겠습니다.
- 전역 스코프: 가장 바깥의 영역을 의미합니다.
- 지역 스코프: 함수 내부(함수 레벨 스코프) 혹은 블록 내부(블록 스코프)의 영역을 의미합니다.
- 함수 레벨 스코프: 함수에 의해서만 지역 스코프가 생성되는 것을 의미합니다.
- 블록 레벨 스코프 : 코드 블록 내부에서 지역 스코프가 생성되는 것을 의미합니다.
- 정적 스코프(렉시컬 스코프) : 호출 스택과 관계없이 선언 시점에 상위 스코프를 결정합니다.
- 동적 스코프 : 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정하는 것입니다.
참고로 자바스크립트는 정적 스코프(렉시컬 스코프)를 따릅니다.
전역 스코프
- 가장 바깥의 영역을 의미합니다.
- 전역 스크프에서 선언한 변수를 전역 변수라 합니다.
위의 예제를 보시면 global은 가장 바깥의 영역에서 선언되었으며, 전역 스코프에서 선언한 전역 변수는 어디서든 참조가 가능합니다.
지역 스코프
- 함수 내부(함수 스코프) 혹은 블록 내부(블록 스코프)의 영역을 의미합니다.
- 지역 스코프에서 선언한 변수를 지역 변수라 합니다.
위의 예제를 보시면, 지역 스코프에서 선언한 지역변수는 지역 스코프 안에서만 참조할 수 있고 지역 밖에서는 정의되지 않는다는 에러를 발생시킵니다.
함수 레벨 스코프
- 함수에 의해서만 지역 스코프가 생성되는 것을 의미합니다.
(다른 의미로 블록 ({ })에서는 지역 스코프가 생성되지 않는 것을 의미합니다.) - 함수 내부에서만 접근할 수 있습니다.
- 자바스크립트 var 가 함수 레벨 스코프에 속합니다.
위의 예제를 보시면 var는 함수 레벨 스코프이기 때문에 블록 내부에 선언을 해줘도 블록 내부에서는 지역 스코프가 생성이 되지 않아 블록 밖에서도 변수 x를 참조할 수 있는 것입니다.
그렇기 때문에 위의 두 예제의 결과 값은 결국 지역 스코프는 함수 레벨에서 생성된 것입니다.
블록 레벨 스코프
- 코드 블록 내부에서 지역 스코프가 생성되는 것을 의미합니다.
- javascript에서 let, const가 블록 레벨 스코프 갖습니다.
위의 예제를 보시면 let은 블록 레벨 스코프이기 때문에 블록 내부에 선언을 해주면 블록 내부에서 따로 지역 스코프가 생성이 됩니다.
그렇기 때문에 조건문의 블록 외부에서는 블록 내부의 지역변수를 참조할 수 없습니다.
위와 같은 경우에는 블록 내부에서 생성된 지역 변수를 외부에서 참조 할 수 없어 에러가 발생한 경우입니다.
정적 스코프(static scope, 렉시컬 스코프, Lexical scope)
- 호출 스택과 관계없이 선언 시점에 상위 스코프를 결정합니다.
- javascript는 정적 스코프의 특징을 가지고 있습니다.
위의 예제를 살펴보면 getName() 선언 시점에 name은 상위 스코프는 전역 스코프이며, 전역 변수를 참조하고 있기 때문에 setName() 내부에서 호출을 하든 어디에서 하든 전역 변수의 name을 참조합니다.
동적 스코프 (Dynamic Scoping)
- 정적 스코프와는 반대로 동적 스코프의 선언은 런타임 도중에 실행 콘텍스트나 호출 콘텍스트에 의해 결정됩니다.
- 즉, 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정하는 것입니다.
주의!! 위의 예제는 임의로 제가 예시를 보여드리기 위해 작성한 것입니다. javascript는 정적 스코프라 결과가 위와 같이 나올 수 없습니다.
위의 예제를 보면 getName()의 선언에서 상위 스코프가 결정되는 것이 아니라 호출 시점에 결정되는 것을 볼 수 있습니다.
- 첫 번째 결과에서는 호출 시점이 전역 스코프를 상위 스코프로 갖습니다.
- 두 번째 결과에서는 setName() 내부에서 호출되었기 때문에 setName() 함수 레벨의 스코프를 상위 스코프로 갖습니다.
자바스크립트 스코프의 특징 정리
- var: 함수 레벨 스코프
- let, const: 블록 레벨 스코프
- 정적 스코프의 특징을 갖고 있습니다.
오늘 준비한 내용은 여기까지 입니다.
읽어주셔서 감사합니다 :)
좋아요 및 댓글 달아주시면 감사하겠습니다 :)
궁금한 내용 및 잘못된 내용을 위한 댓글 혹은 토론하고 싶은 댓글은 백번, 만 번 환영입니다!!!
'언어 > JavaScript' 카테고리의 다른 글
자바스크립트(JavaScript) - find(), findIndex() 배열의 내장함수 #7 [엄탱 개발일지] (2) | 2022.07.25 |
---|---|
자바스크립트(JavaScript) - trim() string의 내장함수 #1 [엄탱 개발일지] (0) | 2022.07.19 |
자바스크립트(JavaScript) - concat(), join() 배열의 내장함수 #6 [엄탱 개발일지] (4) | 2022.07.15 |
자바스크립트(JavaScript) - reduce() 배열의 내장함수 #4 [엄탱 개발일지] (2) | 2022.07.12 |
자바스크립트(JavaScirpt) - some() 배열 내장 함수 #3 [엄탱 개발일지] (0) | 2022.07.11 |