
스코프
ㅇ 스코프 이란?
- 프로그램 내 변수에 접근할 수 있는 유효 범위/영역
ㅇ 자바스크립트에서, 스코프 생성 상의 특징
- 위치에 따른 스코프의 생성 : 전역 범위, 함수 범위, 블록 범위로 생성 가능
. 전역 스코프 : 프로그램 어디에서나 접근 가능 (var 선언자)
. 함수 스코프 : 함수 내에서 만 접근 가능 (var 선언자)
. 블록 스코프 : 해당 블록 내에서 만 접근 가능 (let 선언자, const 선언자)
- 시간에 따른 스코프의 생성
- 정적 스코프 (정적 메모리 할당)
. 컴파일러 번역 시에, 변수 영역이 결정됨
. 어휘적 범위(Lexical Scope, 렉시컬 스코프) 라고도 함
. 함수를 정의할 때, 구문 해석 만으로도,
.. 어떤 변수가 그 함수 스코프에 있는지를 알 수 있음
. 즉, 코드 작성 시점에 스코프가 결정됨
- 동적 스코프 (동적 메모리 할당)
. 실행시에 만 비로소 변수 영역이 결정점
. 함수를 실행할 때 만, 비로소 어떤 변수가 그 함수 스코프에 있는지 알 수 있게됨
호이스팅 (Hoisting)
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
function sayHi() {
phrase = "Hello"; // (*)
if (false) {
var phrase;
}
alert(phrase);
}
sayHi()
바로 위 예제에서 if (false) 블록 안 코드는 절대 실행되지 않지만, 이는 호이스팅에 전혀 영향을 주지 않습니다. if 내부의 var 는 함수 sayHi의 시작 부분에서 처리되므로 (*)로 표시한 줄에서 phrase는 이미 정의가 된 상태인 것이죠. 선언은 호이스팅 되지만 할당은 호이스팅 되지 않습니다.
ㅇ 변수 호이스팅 (Variable Hoisting)
- 변수 선언의 끌어올림
. 중간 부분에서 변수 선언을 하여도,
. 마치 그 변수가 첫머리에 선언된 것 처럼 취급됨
- 결국, 변수 선언 및 변수 할당이 분리됨
ㅇ 함수 호이스팅 (Function Hoisting)
- 함수 선언의 끌어올림
. 함수 선언문 형태(명시적 함수)로 정의한 함수의 유효 범위는,
. 코드의 맨 처음부터로 취급됨
* 단, 함수 표현식 형태로 선언되는 경우는 호이스팅되지 않음
※ 호이스팅은, 자바스크립트 고유한 특성으로 다른 프로그래밍 언어와는 차별됨
var만의 특성은 대부분의 상황에서 좋지 않은 부작용을 만들어낸다. let이 표준에 도입된 이유가 바로 이런 부작용을 없애기 위해서이다. 변수는 블록 레벨 스코프를 갖는 게 좋으므로 이제는 let과 const를 이용해 변수를 선언하는 게 대세가 되었다.
TDZ (Temporal Dead Zone)
TDZ 시맨틱은 선언 전에 변수에 접근하는 것을 금지한다. TDZ는 징계를 내린다: 변수 선언 전에 어떤 것도 사용하지 않는다.
ref. https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/
자바스크립트는 정의되지 않았지만 변수의 메모리 할당 단계 호이스팅이 발생하고 스레드 실행 단계에서 변수에 액세스할 수 있으므로 결과적으로 값이 정의되지 않은 것으로 나타난다. let & const 가 사용되었을 때 자바스크립트 개발자가 좋은 코드를 작성하고 디버깅을 쉽게 하기 위해 액세스에 대한 몇 가지 제한이 있다. 그래서 TDZ 새로운 개념이 등장하여 제공하기 전에 일부 데이터에 액세스하기 때문에 오류를 잡는 데 도움이 된다.
ㅇ 함수 호이스팅 (Function Hoisting)
- 함수 선언의 끌어올림
. 함수 선언문 형태(명시적 함수)로 정의한 함수의 유효 범위는,
. 코드의 맨 처음부터로 취급됨
ㅇ 함수 표현식 호이스팅 X => 변수 호이스팅
변수 호이스팅은 변수 생성 및 초기화와 할당이 분리되어 진행된다. 호이스팅된 변수는 undefined로 초기화 되고 실제값의 할당은 할당문에서 이루어진다.
변수 선언
ㅇ 명시적인 변수 선언은,
var,let 라는 예약어 만으로 가능ㅇ 변수명 규칙
영문자, $, _ (3 종류) 만으로 시작해야 함상수 선언
ㅇ const 키워드로 선언
ㅇ 특징
반드시 초기값 할당해야 함함수 이란?
ㅇ [프로그래밍 일반]
ㅇ [자바스크립트 언어]
C 언어의 함수,자바 언어의 메서드 등과는 달리,실행 execute 가능(호출 invoke 가능),참조 reference 가능 특징 둘다 갖는 특별한 객체임자바스크립트 함수의 특징 (통상의 프로그래밍 언어와의 차별점)
ㅇ 함수를 값 처럼 할당/대입할 수 있으며, 그 방법이 다양함
변수에 함수를 할당할 수 있음객체의 프로퍼티에 함수를 할당할 수 있음배열 내 원소에도 함수를 할당(정의,저장)할 수 있음ㅇ 함수를 매개변수로 전달할 수도 있으며, 함수 그 자체를 반환할 수도 있음
ㅇ 함수 정의(생성) 방식이 다양함 관련 링크
명시적 함수(함수 선언문) 형식에 의한 방법 이외에도,익명 함수 형식함수 리터럴 형식함수 객체 생성자 형식 등ㅇ 자바스크립트 함수는 일종의 객체 임 ☞ Function 객체, 자바스크립트 객체 참조
__proto__라는 접근자 프로퍼티는, Object.prototype 객체의 프로퍼티를 상속 받음ㅇ 객체 형태이긴 하나, 하나의 독립된 데이터타입으로 취급됨
자바스크립트 함수의 생성 방법 및 함수 형태의 종류
※ 함수 생성 방법의 종류
ㅇ 함수 형태의 종류
자바스크립트 함수에서의 인수(매개변수,파라미터)
※ ☞ 자바스크립트 함수 인수 참조
자바스크립트 함수 호출 및 참조
ㅇ 함수 호출(invoke) : 함수명 뒤에 소괄호 ()를 쓰면 호출(실행)됨
ㅇ 함수 참조(reference) : 함수명 뒤에 괄호()를 쓰지 않으면, 함수를 참조 만 함
함수 메모이제이션 (Memoization)
ㅇ 함수를 호출했을 때, 그 인수와 반환값을 한 쌍으로 만들어 저장해 두는 기법
컨텍스트
ㅇ 상황, 맥락, 문맥 상의 의미 등으로 이해되는 용어
ㅇ 사실상, 컨텍스트는,
ㅇ 전산 뿐만 아니라 방송, 예술 등의 분야에서도 널리 사용되는 용어
전산] 컴퓨터 내부 (하드웨어 관점)
ㅇ 컨텍스트는 컴퓨터 내부에서 볼 때,
ㅇ Context Switching (문맥 교환)
전산] 프로그램 내부 (소프트웨어 관점)
ㅇ 그때그때 상황에 맞게끔, 실행/판단/결정 등을 해야하는 부분
전산] 자바스크립트 실행 컨텍스트 (Execution Context)
ㅇ 실행에 필요한 다양한 정보를 형상화하고, 이들을 목록화 관리하기 위한, 추상적인 개념
ㅇ 실행 컨텍스트의 관리 및 보유 형태
ㅇ 만일, 자바스크립트 엔진이,
실행 가능한 코드를 만나면, 그 코드를 평가해서, 실행 컨텍스트를 만들어냄
. 例)
.. 만일, 함수를 호출하면,
.. 현재 실행중인 코드의 작업을 잠시 멈추고,
.. 함수 코드가 평가되면서,
.. 실행 컨텍스트 영역을 생성하고,
.. 이때 생성된 함수 실행 컨텍스트는, 실행 컨텍스트 스택에 푸시되고,
.. 실행 흐름이, 실행 컨텍스트 스택 상의 그 실행 컨텍스트로 이동하고,
.. 함수 안팎의 환경을 찾아내어, 실행되어지며,
.. 함수 실행이 종료되면, 실행 컨텍스트 스택에서 팝되어 제거됨
실행 가능한 코드의 例)
. 전역 코드 : 가장 바깥쪽에 존재하는 것
. 함수 코드
. eval 함수
. 모듈 코드
콜 스택이란, 함수의 호출을 스택 방식으로 저장하는 자료구조이다. 즉, 실행 컨텍스트에 콜 스택을
실행 중인 함수의 실행 절차에 대한 정보는 해당 함수의 실행 컨텍스트(execution context) 에 저장됩니다.
실행 컨텍스트는 함수 실행에 대한 세부 정보를 담고 있는 내부 데이터 구조입니다. 제어 흐름의 현재 위치, 변수의 현재 값, this의 값(여기선 다루지 않음) 등 상세 내부 정보가 실행 컨텍스트에 저장됩니다.
함수 호출 일 회당 정확히 하나의 실행 컨텍스트가 생성됩니다.
함수 내부에 중첩 호출이 있을 때는 아래와 같은 절차가 수행됩니다.
현재 함수의 실행이 일시 중지됩니다.
중지된 함수와 연관된 실행 컨텍스트는 실행 컨텍스트 스택(execution context stack) 이라는 특별한 자료 구조에 저장됩니다.
중첩 호출이 실행됩니다.
중첩 호출 실행이 끝난 이후 실행 컨텍스트 스택에서 일시 중단한 함수의 실행 컨텍스트를 꺼내오고, 중단한 함수의 실행을 다시 이어갑니다.
그냥, 여기 가면 잘 나와 있어서, 아래 글을 참고해서 보는 것이 나을 것 같다.
정확히는 콜 스택 보다는, JavaScript의 이벤트 루프에 관한 글이지만, 구동 원리에 대해 이해하는데 추천
https://meetup.toast.com/posts/89
function a(){
// 여기서 r 정의
var r = 1;
function b(){
// 여기선 r 정의는 하지 않아도 r의 값이 출력이 된다.
console.log(r);
}
b();
}
// 이렇게 r을 var 선언해도, a() 호출하면 값으로 1나옴
// 이런식으로 스코프 체인이 형성됨
var r= 2;
a(); //1
변수 은닉화
변수 은닉화는 변수가 전역 범위에 노출되지 않고, 지역 범위에 노출되게 하면서 전역범위에 불렀을 때 불러 올 수 있게끔 만드는 것인데, 주로 즉시 실행 함수 표현식(immediately-invoked function expressions) 을 이용하여 만들 수 가 있다.
클로져 이용(Closer)클로저 (Closure)
ㅇ 함수와 함수의 참조환경
ㅇ 부모 함수의 지역 변수의 참조를 갖는 자식 함수 블록
클로저의 특징
ㅇ 변수를 은닉하여 지속성을 보장할 수 있는 등
- 특정 스코프 내 함수를 정의하면,
- 해당 스코프는 더 오래 유지 됨
ㅇ 접근 못하던 것에 대한 접근 방법이 생김
- 함수를 정의해서 클로저를 만들면,
- 접근할 수 없었던 것들에 대해 접근할 방법이 생김
ㅇ 데이터와 데이터를 조작하는 함수를 하나로 묶을 수 있음
- 마치 객체지향 프로그래밍과 유사하게 취급 가능
. 클로저를 감싸고 있는 부모 함수 => 생성자
. 클로저를 참조하는 외곽 함수 내 지역 변수 => 프로퍼티
. 클로저 자신 => 메소드
. 함수 호출 = > 인스턴스화
. 반환되는 클로저를 대입하게된 변수 => 인스턴스
ㅇ [자바스크립트]
- 자바스크립트의 모든 함수는, 클로저를 정의 가능
즉시 실행 함수 (IIFE) 이용
ㅇ 함수 정의 및 호출/실행이 동시에 이루어지는 함수 형태
ㅇ 구문 형식 : (function () { ... })();
Class 이용 - 모던 자바스크립트
getter를 이용하여, 주어진 값을 꺼내 쓸 수 있다.
let b = 1;
function hi () {
const a = 1;
let b = 100;
b++;
console.log(a,b);
}
//console.log(a);
/////////////////////////////////////////
console.log(b);
hi();
console.log(b);
let b = 1;
let a; // 전역변수에 a를 추가
function hi () {
a = 1;
let b = 100;
b++;
console.log(a,b);
}
// a가 b와 달리 접근이 가능하지 않은 것은 함수 내부에서만 접근 가능하고
// 함수를 불러야지만, 변수에 접근 가능한 상태로 은닉화를 시킨 형태이다.
console.log(b); // 1
// 함수를 실행 뒤에 a를 출력할 수 잇다.
hi(); //1 101
console.log(a) // 1
console.log(b); // 1
ref. https://ko.javascript.info/var, https://www.geeksforgeeks.org/what-is-the-temporal-dead-zone-in-es6/, http://www.ktword.co.kr/, https://ui.toast.com/weekly-pick/ko_20191014?fbclid=IwAR3fiR4wiv8kszL6Fz2KqwHpv-bTL8tNHElRN0q0ky5kpOP5BMqMS0wc-9k, https://ko.javascript.info/recursion,