티스토리 뷰
스코프 체인에 의한 함수 검색
// 전역 함수
function foo() {
console.log('global function foo');
}
function bar() {
// 중첩 함수
function foo() {
console.log('local function foo');
}
foo(); // ①
}
bar();
함수 선언문으로 함수를 호출하면, 런타임 이전에 함수 객체가 먼저 생성된다.
위 예제는 따라서 동일한 함수 이름과 동일한 이름의 식별자에 할당된다. 따라서 foo를 호출하면 먼저 함수를 가르키는 foo를 검색하게 되기 때문에, 로컬함수가 먼저 호출되게 된다.
함수도 식별자에 할당되기 때문에, 스코프는 식별자를 검색하는 규칙이라고 하는게 적합하다.
함수레벨 스코프
지역스코프는 함수에 의해서 생성된다.
다른 모든 언어는 모든 코드블럭(if,for,while,...)등에 의해 지역 스코프를 생성한다.
하지만 var로 선언된 변수는 오로지 함수 몸체만을 지역 스코프로 인정한다.
이러한 특성을 함수레벨 스코프라고 한다.
var x = 1;
if (true) {
// var 키워드로 선언된 변수는 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정한다.
// 함수 밖에서 var 키워드로 선언된 변수는 코드 블록 내에서 선언되었다 할지라도 모두 전역 변수다.
// 따라서 x는 전역 변수다. 이미 선언된 전역 변수 x가 있으므로 x 변수는 중복 선언된다.
// 이는 의도치 않게 변수 값이 변경되는 부작용을 발생시킨다.
var x = 10;
}
console.log(x); // 10
이처럼 if코드블럭 안에 var x라는 중복된 이름을 가진 변수를 선언한다고 하더라도, 둘은 똑같이 전역변수로 여겨지기 때문에 의도치않게 값이 재할당 된다.
var i = 10;
// for 문에서 선언한 i는 전역 변수다. 이미 선언된 전역 변수 i가 있으므로 중복 선언된다.
for (var i = 0; i < 5; i++) {
console.log(i); // 0 1 2 3 4
}
// 의도치 않게 변수의 값이 변경되었다.
console.log(i); // 5
위의 for문 속의 var도 함수 레벨 스코프만을 갖기 때문에, 같은 전역변수로써 여겨지기 때문에 값이 재할당 되는 결과를 가진다.
때문에, 앞으로 개발을 할 때에는 의도치 않은 오류를 야기하는 var를 사용하는 일은 절대! 없어야한다는걸 명심해야한다.
렉시컬 스코프
용어 자체가 생소한 렉시컬 스코프란 무엇일까?
예제를 통해 확인해보자
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // ?
bar(); // ?
첫번째 방식의 함수 호출 방식을 보면, foo내부에서 bar라는 함수를 호출하고 있다.
이 방식으로 함수를 호출한다면, bar함수의 상위 스코프는 foo의 지역스코프와 전역 스코프일 것이다.
해당 방식을 동적 스코프라고 한다.
함수를 정의하는 시점에는 함수가 어디서 호출될지 알 수 없기 때문에, 함수가 호출되는 시점에서 동적으로 상위 스코프를 정해야 하기 때문이다.
두번째 방식을 바로 렉시컬 스코프, 혹은 정적 스코프라고 한다.
상위스코프가 동적으로 변하지 않고 함수가 정의되는 시점에 상위 스코프가 정적으로 결정되기 때문이다.
대부분의 프로그래밍 언어들은 렉시컬스코프, 정적 스코프의 방식을 사용한다.
따라서 JS도 마찬가지로, 함수를 어디서 호출했나는 해당 함수의 스코프에 영향을 끼치지 않고 함수를 어디서 정의했느냐에 의해 함수의 상위 스코프가 결정된다.
따라서 위의 코드는 foo가 x를 10으로 재할당 했다고 하더라도, bar의 상위 스코프는 전역 스코프이기 때문에
foo에서 호출한 bar도 전역변수인 var x=1 을 참조하고 있기 때문에, 1을 호출하고 전역에서 호출한 bar도 또한 1을 호출하게 됨으로, 1이 두번 호출되는 결과를 확인할 수 있다.
'스터디 자료' 카테고리의 다른 글
| [모던 자바스크립트] 19장 프로토타입 (0) | 2024.04.24 |
|---|---|
| [딥다이브]함수 객체의 프로퍼티 (0) | 2024.04.11 |
| [객체란?] (2) | 2024.01.11 |
| 17주 기초 교육 학습자료(11주차~14주차) (0) | 2023.10.15 |
| 17주 기초 교육 학습자료(1주차~10주차) (0) | 2023.10.15 |
- Total
- Today
- Yesterday
- Front-End
- delete
- Vite
- DOM
- html #css #코딩 #공부
- JavaScript
- MAP
- 공부
- yarn 4
- async
- 심볼
- 1일차
- forEach
- CSSOM
- set
- 단축평가
- 타입변환
- React
- 자바스크립트
- http
- 호이스팅
- 렌더트리
- Get
- TypeScript
- yarn berry
- node
- defer
- 옵셔널체이닝연산자
- JS
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |