스코프
•
선언된 변수에 대해서 접근할 수 있는 유효한 범위
•
식별자를 검색할 때 사용되는 규칙
•
스코프 = 식별자의 유효범위
•
== 상속
호이스팅
•
스코프 단위로 동작되고, 스코프의 선두로 끌어 올려진 것 처럼 동작하는 자바스크립트의 고유의 특징
계층적 구조
•
하위 스코프는 상위 스코프에 접근 가능
•
상위 스코프는 하위 스코프에 접근 불가
/**
* 하위 스코프 => 상위 스코프를 접근하는 경우
*/
const ScopeComponent = () => {
// 상위 스코프
const userId = "Honey";
const fn_controlScope = () => {
// 하위 스코프
console.log("상위 스코프 접근 가능", userId);
};
return (
<></>
)
}
JavaScript
복사
/**
* 상위 스코프 => 하위 스코프를 접근하는 경우
* => error
*/
const ScopeComponen2 = () => {
const fn_controlScope = () => {
// 하위 스코프
const userId = "Honey"
};
// 상위 스코프
console.log(userId); // Error!-Cannot find name 'userId'.
return (
<></>
)
}
JavaScript
복사
스코프 동작 별 구분
정적 스코프 (Static Scope) = 렉시컬 스코프(Lexical Scope)
•
JS 사용 스코프 - 함수를 어디서 정의했는지
•
함수를 선언한 시점에 스코프를 결정하는 방식
•
함수가 중첩되어 있을 때, 내부 함수 내에 해당 변수가 존재하지 않을 경우 상위 스코프에서 해당 변수를 찾는 방식
◦
중첩 예시 1
let x = "Global Variable"; // 전역 변수
// 함수 선언
function func1() { // 1
let x = "Local Variable"; // 지역 변수
func2(); // 2
};
// 함수 선언
function func2() {
console.log(x); // 3
};
func1(); // Global Variable
func2(); // Global Variable
JavaScript
복사
◦
중첩 예시 2
let s = "Global Variable"; // 4
// 함수 선언
function func1() {
let s = "Local Variable"; // 2
// 함수 선언 당시 지역 변수의 스코프를 가진다.
console.log(s); // Local Variable 2
func2(); // 3
}
// 함수 선언
function func2() {
// 함수 선언 당시의 전역 변수의 스코프를 가진다.
console.log(s); // Global Variable 4
}
// 함수 1 호출
func1(); // 1
JavaScript
복사
동적 스코프 (Dynamic Scope)
•
JS에서 사용X
•
함수를 호출한 시점에 스코프를 결정하는 방식
•
선언은 런타임 도중에 실행 컨텍스트나 호출 컨텍스트에 의해 결정
레벨 별 구분
전역 스코프 (Global Scope)
•
전역으로 선언된 변수에 대해 접근과 조작이 가능한 유효한 범위
import { useEffect } from "react";
// 전역 스코프(Global Scope) 변수 선언
const USER_ID = "honey"
const ScopeComponent = () => {
// 전역 스코프(Global Scope) 변수 선언
const HONEYCOMB = "honeybee"
const fn_controlScope = () => {
console.log(USER_ID); // 전역 스코프(Global Scope) 변수 접근
console.log(HONEYCOMB); // 전역 스코프(Global Scope) 변수 접근
};
return (
<></>
)
}
export default ScopeComponent;
JavaScript
복사
지역 스코프 (Local Scope)
•
변수가 함수 혹은 블록 내에서 접근(호출)이 가능한 유효한 범위
•
함수 내에서 유효한 경우의 함수 스코프와 블록 내에서 유효한 경우의 블록 스코프
import { useEffect } from "react";
const ScopeComponent = () => {
const fn_controlScope = () => {
let userId = "honeybee"; // 함수 스코프(Function Scope) 변수 선언
console.log(userId); // 함수 스코프(Function Scope) 변수 접근
if(userId.length > 1){
const honey = "sweet"; // 블록 스코프(Block Scope) 변수 선언
console.log(honey); // 블록 스코프(Block Scope) 변수 접근
}
console.log(honey); // 블록 스코프(Block Scope) 변수 접근
// Error - honey' is not defined.
};
console.log(userId); // 함수 스코프(Function Scope) 변수 접근
// Error - 'userId' is not defined.
return (
<></>
)
}
export default ScopeComponent;
JavaScript
복사
함수 스코프(Function Scope)
•
선언한 변수가 함수 내에서 유효한 범위
import { useEffect } from "react";
const ScopeComponent = () => {
const fn_controlScope = () => {
const userId = "honey"; // 함수 스코프(Function Scope) 변수 선언
console.log(userId); // 함수 스코프(Function Scope) 변수 접근
};
console.log(userid); // Error ! - Cannot find name 'userid'.
return (
<></>
)
}
export default ScopeComponent;
JavaScript
복사
블록(중괄호 내) 스코프 (Block Scope)
•
선언한 변수가 블록(중괄호 내)에서 유효한 범위
import { useEffect } from "react";
const ScopeComponent = () => {
const fn_controlScope = () => {
const userId = "honey"; // 함수 스코프(Function Scope) 변수 선언
if (userId.length > 1) {
const isSuccess = true; // 블록 스코프(Block Scope) 변수 선언
console.log(isSuccess); // 블록 스코프(Block Scope) 변수 접근 - true
}
return isSuccess; // Error! - Cannot find name 'isSuccess'.
}
return (
<></>
)
}
export default ScopeComponent;
JavaScript
복사
스코프 체인(Scope Chain)
•
스코프가 계층적으로 연결된 것
•
일종의 리스트
•
현재 스코프 레벨에서 변수가 존재하지 않는 경우 상위 스코프에서 찾는 것
◦
스코프를 안에서 바깥쪽으로 단계적으로 탐색하는 과정 (내부 -> 외부 -> 전체)
렉시컬 환경
•
스코프 체인은 실행컨텍스트의 렉시컬 환경을 단방향으로 연결한 것
•
스코프 자료구조
스코프 체인에 의한 변수 검색
•
상위 스코프에서 유효한 변수는 하위 스코프에서도 참조O
•
하위 스코프의 변수를 상위 스코프에서 참조X
var과 let의 중복 선언
function bar() {
var x = 1; // 1
var x = 2; // 2
let x2 = 1;
let x2 = 2; // SyntaxError
}
JavaScript
복사
•
var은 js엔진에 의해 두 번째 var x = 2; 선언시 var 키워드가 없는 것처럼 동작
•
let은 같은 스코프 내에서 중복 선언을 허용하지 않기 때문에 두 번째 선언을 할 시, SyntaxError를 발생