안녕하세요. 오늘은 유튜브 코드팩토리님의 자바스크립트 강의 영상을 참고하여 스코프에 대해 좀 더 자세히 작성해보도록 하겠습니다.
Scope란?
스코프는 변수가 유효하게 작동할 수 있는 범위를 말합니다. 쉽게 말해서 변수를 사용할 수 있는 '영역'이라고 생각할 수 있습니다.
Scope 종류
1. 전역 스코프(Global Scope)
2. 함수 스코프(Function Scope)
3. 블록 스코프(Block Scope)
전역 스코프(Global Scope)
전역 스코프는 코드 전체에서 접근할 수 있는 변수를 의미합니다. 함수 바깥이나 블록 바깥에서 변수를 선언하면 전역 스코프에 속합니다.
let globalVariable = "나는 전역 변수";
function myFunction() {
console.log(globalVariable); // 출력 : 나는 전역 변수
}
myFunction();
console.log(globalVariable); // 출력 : 나는 전역 변수
위 코드에서 'globalVariable'은 전역 변수로, 함수 내부와 외부 모두에서 접근할 수 있습니다.
함수 스코프(Function Scope)
함수 스코프는 함수 내부에서만 접근할 수 있는 변수입니다. 'var' 키워드를 사용해서 변수를 선언하면 이 함수 스코프를 따르게 됩니다.
function myFunction() {
var functionVariable = "나는 함수 변수";
console.log(functionVariable); // 출력: 나는 함수 변수
}
myFunction();
console.log(functionVariable); // 오류: functionVariable은 정의되지 않음
'functionVariable'은 함수 내부에서만 유효하며 함수 바깥에서는 접근할 수 없습니다.
블록 스코프(Block Scope)
블록 스코프는 중괄호 '{}'로 둘러싸인 코드 블록 내(예를 들면 if, for, while 등)에서만 접근할 수 있는 변수를 의미합니다. 'let', 'const' 키워드를 사용하면 블록 스코프를 따르게 됩니다.
if (true) {
let blockVariable = "나는 블록 변수";
const blockConstant = "나는 블록 상수";
console.log(blockVariable); // 출력: 나는 블록 변수
console.log(blockConstant); // 출력: 나는 블록 상수
}
console.log(blockVariable); // 오류: blockVariable은 정의되지 않음
console.log(blockConstant); // 오류: blockConstant는 정의되지 않음
'blockVariable'과 'blockConstant'는 'if'문 블록 안에서만 유효하며, 블록을 벗어나면 접근할 수 없습니다.
var i = 999;
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(`i in global scope : ${i}`);
// 출력:
// 0 1 2 3 4 5 6 7 8 9
// i in global scope : 10
'var'는 블록 스코프를 만들지 않기 때문에 전역 스코프의 'i'를 덮어씁니다.
let i = 999;
for (let i = 0; i < 10; i++) {
console.log(i);
}
console.log(`i in global scope : ${i}`);
// 출력:
// 0 1 2 3 4 5 6 7 8 9
// i in global scope : 999
'let'은 블록 스코프를 생성하므로 전역 스코프의 'i'와 다른 'i' 변수를 사용합니다.
var, let, const의 차이
- var : 함수 스코프를 따릅니다. 함수 내 어디서든 접근할 수 있지만 블록 스코프를 따르지 않아 블록 외부에서도 접근이 가능합니다. 또한, 변수 선언 전에 사용할 수 있으며 이는 호이스팅이라고 합니다.
- let : 블록 스코프(+함수 스코프)를 따릅니다. 블록 내에서만 유효하며, 변수 선언 전에 사용할 수 없습니다.
- const : let과 마찬가지로 블록 스코프(+함수 스코프)를 따르지만 변수의 값을 변경할 수 없습니다. 반드시 선언과 동시에 초기화해야 합니다.
Lexical Scope?
자바스크립트는 Lexical Scope(또는 정적 스코프)를 따릅니다. Lexical Scope는 변수가 어디에서 선언되었는지에 따라 스코프가 결정되는 방식을 의미합니다. 이 스코프는 코드가 작성된 시점에서 결정되며 실행 시점에서 바뀌지 않습니다.
Lexical Scope : 선언된 위치가 상위 스코프를 정한다. ↔ Dynamic Scope : 실행한 위치가 상위 스코프를 정한다.
var numberOne = 20;
function levelOne() {
var numberOne = 40;
function levelTwo() {
var numberTwo = 99;
console.log(`levelTwo numberTwo : ${numberTwo}`);
console.log(`levelTwo numberOne : ${numberOne}`); // 상위 스코프의 numberOne 출력
}
levelTwo();
console.log(`levelOne numberOne : ${numberOne}`);
}
levelOne();
// 출력:
// levelTwo numberTwo : 99
// levelTwo numberOne : 40
// levelOne numberOne : 40
console.log(numberOne); // 출력: 20
console.log(numberTwo); // 오류: numberTwo는 정의되지 않음
- 'levelTwo()' 함수는 'levelOne()' 함수의 스코프에 접근할 수 있습니다.
- 'numberOne'는 'levelOne()' 함수에서 정의된 변수로 'levelTwo()'에서 접근 가능합니다.
- 'numberTwo'는 'levelTwo()' 내부에서만 유효합니다. (하위 스코프에 접근할 수 없습니다.)
캡슐화와 프라이빗 변수
자바스크립트에서 스코프를 활용하여 변수를 외부에서 직접 접근하지 못하게 하고, 함수 등을 통해서만 접근할 수 있게 만들 수 있습니다. 이를 통해 캡슐화를 구현할 수 있습니다.
function Idol(name, year) {
this.name = name; // 객체의 속성으로 설정됨
var _year = year; // 함수 내부에서만 유효한 변수로 설정됨
this.sayNameAndYear = function() {
return `안녕하세요. 저는 ${this.name}입니다. ${_year}년에 태어났습니다.`;
}
}
const yuJin = new Idol('안유진', 2003);
console.log(yuJin.sayNameAndYear()); // 출력: 안녕하세요. 저는 안유진입니다. 2003년에 태어났습니다.
console.log(yuJin.name); // 출력: 안유진
console.log(yuJin._year); // 출력: undefined
위 예제에서 'this.name'은 생성된 객체의 속성으로 설정되어 외부에서 접근할 수 있지만 'var'로 선언된 '_year' 변수는 함수 내부에서만 유효하기 때문에 외부에서 직접 접근할 수 없고 sayNameAndYear() 메서드를 통해 접근하여 '_year' 변수를 프라이빗(private) 변수처럼 사용하였습니다.
'Languages > JavaScript' 카테고리의 다른 글
[JS] 비동기 프로그래밍(2) : 프로미스(Promise) (0) | 2024.08.23 |
---|---|
[JS] 비동기 프로그래밍(1) : 콜백 함수(Callback Function) (0) | 2024.08.23 |
[JS] 배열 메소드(Array Method) 총정리 (0) | 2024.08.22 |
[JS] 데이터 타입 총정리 (0) | 2024.08.21 |
[JS] Copy by Value & Copy by Reference (+ Spread Operator) (0) | 2024.08.21 |