스코프는 자바스크립트를 이용하는 데에 있어 필수적인 개념입니다.
이 포스팅 뒤로 클로저에 대해 알아볼 건데,
그전에 앞서 스코프의 정의가 먼저 필요하기 때문에 스코프 정의를 먼저 정리해보겠습니다.
스코프(Scope)의 정의
함수를 작성할 때 아래와 같이 중괄호 '{ }'를 이용하여 함수의 범위를 작성합니다.
function hello(){
alert('함수 작성');
}
즉, [변수가 영향을 미치는 범위], [변수의 유효 범위], [코드가 유효한 범위]라고 할 수 있으며 규칙입니다.
그리고 스코프의 종류에따라 변수, 함수, 코드 등의 유효 범위가 달라질 수 있습니다.
스코프(Scope)의 종류
스코프의 종류에 대해 알기 쉽게 알아봅시다.
1.동작
- 정적 스코프
- 동적 스코프
2.레벨
- 함수 레벨 스코프
- 블록 레벨 스코프
- 전역 스코프
- 지역 스코프
3.추가로 알아야할 사항
- 스코프 체인
스코프가 단순히 범위라고만 알고 있으면 안 되는 이유는 선언의 시점에 따라 값이 달라질 수 있기 때문입니다.
그래서 동작에 따라 나뉘는 정적 스코프, 동적 스코프에 대해 알아봅시다.
동작
- 정적 스코프
Javascript는 정적 스코프의 특성을 가지고 있습니다.
정적 스코프의 규칙에 따라 호출 스택과 관계없이 선언 시점에 스코프를 결정합니다.
function home(){
var sister = '여동생 숙제 중';
}
function getSister(){
console.log(sister); // sister is not defined
}
getSister();
sister is not defined이 되는 이유는 정적 스코프이기 때문입니다.
함수를 호출할 때가 아니라 선언할 때 스코프가 정해지고 외부 변수는 내부 변수에 접근할 수 없기 때문에 not defined이 됩니다.
- 동적 스코프
정적 스코프와는 반대로 동적 스코프의 선언은 런타임 도중에 실행 콘텍스트나 호출 콘텍스트에 의해 결정됩니다.
[정적 스코프일 때]
var sister = '여동생 숙제 중';
function home(){
var sister = '여동생 집에없다';
getSister();
}
function getSister(){
console.log(sister); // 여동생 숙제 중
}
home();
[동적 스코프일 때]
var sister = '여동생';
function home(){
var sister = '여동생 집에없다';
getSister();
}
function getSister(){
console.log(sister); // 여동생 집에없다
}
home();
즉,
정적 스코프는 소스코드가 작성된 콘텍스트에서 결정되며
동적 스코프는 프로그램 런타임 도중에 실행 콘텍스트나 호출 콘텍스트에서 결정됩니다.
레벨
- 함수 레벨 스코프
var로 선언된 변수, 함수들은 함수 레벨 스코프가 됩니다.
함수가 유효 범위입니다.
function hello(name){
if(name){
var greet = name + '님 안녕하세요';
}
console.log(greet); // 이하나님 안녕하세요
}
hello('이하나');
function이 유효 범위이므로 if 스코프 내에 선언된 greet는 hello 변수 내에서 접근 가능합니다.
아래 블록 레벨과 비교해서 보면 더욱 확실히 개념을 잡을 수 있을 것입니다.
- 블록 레벨 스코프
ES6부터 지원하기 시작한 let, const 키워드로 선언된 변수, 함수들은 블록 레벨 스코프가 됩니다.
블록이 유효 범위입니다.
function hello(name){
if(name){
let greet = name + '님 안녕하세요';
}
console.log(greet); // greet is not defined
}
hello('이하나');
if의 스코프가 유효 범위이므로 greet에 접근하지 못하여 not defined이 나옵니다.
함수 레벨 스코프가 사용하기에는 더 편리하지만 블록 레벨 스코프보다 스코프의 범위가 넓으므로 코드에 대한 복잡성을 증가하는 요인이 됩니다. 따라서 변수의 유효 범위는 좁을수록 좋고 선택이 가능하다면 블록 레벨 스코프를 사용해야 합니다.
- 전역 스코프
전체가 범위며 전역 스코프에서 변수를 선언하게 되면 어디서든지 참조할 수 있는 전역 변수가 됩니다.
하나의 html에서 두 개의 js파일을 로드해서 사용할 때에도 전역 변수는 사용이 가능합니다.
// index.js
var global = '난 글로벌해';
// pages.js
console.log('global'); // 난 글로벌해
전역 변수를 남발하게 되면 변수이나 함수의 중복이 될 가능성이 커지며 코드를 예측할 수 없어집니다.
그렇기 때문에 즉시 실행 함수를 사용해서 전역 변수를 해당 파일(모듈)에서만 범위를 억제하는 방법들이 많이 쓰입니다.
(function(){
var APP = APP || {};
APP.info = {
name : 'chat app',
version : '1.2.1'
};
APP.Start = function(){
// ....
};
console.log(APP.info.name); // chat app
})();
console.log(APP.info.name); // APP is not defined
- 지역 스코프
함수 코드 블록이 만든 스코프로 함수 내부와 하위 함수의 변수와 함수만 참조가 가능합니다.
function local(){
var me = '난 지역이야';
}
function callLocal(){
console.log(me); // me is not defined
}
callLocal();
지역에서 선언한 건 같은 지역에서만 참조가 됩니다.
함수 스코프나 블록 스코프를 생각하면 쉬울 것 같습니다.
추가로 알아야 할 사항
- 스코프 체인(Scope Chain)
내부 함수에서 외부 함수의 변수에 접근은 가능하지만
외부 함수에서 내부 함수의 변수에는 접근할 수 없습니다.
스코프 체인은 내부 함수에서 변수를 찾기 위해 외부 함수로 접근할 때에 탐색을 하게 되는 관계를 말합니다.
스코프의 탐색은 해당 스코프 내부를 먼저 탐색하고 선언된 것이 없다면 한 단계 위의 스코프를 탐색하며 반복적으로 이루어 집니다.
찾을 때까지 과정을 반복하면서 상위 환경을 참조하려고 합니다.
이 과정은 해당 선언을 찾거나 null이 될 때(더 이상의 참조가 불가능할 때) 탐색을 멈춥니다.
이것을 스코프 체인이라고 합니다.
참조 링크
'~2022 > FE-개발 개념' 카테고리의 다른 글
Git Squash 깃 스쿼시, 커밋 연결하기/병합하기 소스트리에서 사용해보기 (0) | 2020.02.24 |
---|---|
git Stash 깃 스태시, 소스트리에서 사용해보기 (1) | 2020.02.24 |
자바스크립트 프로토타입(Prototype)이란? __ 프로토타입링크(Prototype Link)__프로토타입객체(Prototype Object) (1) | 2020.02.14 |
호이스팅(Hoisting)란? (0) | 2020.01.30 |
사파리 브라우저 쿠키(Cookie) 이슈 (0) | 2019.11.27 |
개발 버전표기 대략적으로 이해하기 (0) | 2019.11.15 |
크롬 개발자 툴을 알아보자 (0) | 2019.08.01 |
AOS란? (0) | 2019.06.15 |