컴파일 언어, 스크립트 언어
1. 컴파일 언어
- 컴파일 언어는 소스 코드를 기계어로 번역하는 과정을 거친다.
- 컴파일 언어는 소스 코드를 실행하기 전에 컴파일러를 통해 기계어로 번역한다.
- 컴파일 언어는 실행 속도가 빠르다.
- 컴파일 언어는 실행 파일을 만들어야 하기 때문에, 실행 파일을 만드는 시간이 필요하다.
2. 스크립트 언어
- 스크립트 언어는 소스 코드를 실행하는 과정을 거친다.
- 스크립트 언어는 소스 코드를 실행하기 전에 인터프리터를 통해 기계어로 번역한다.
- 스크립트 언어는 실행 속도가 느리다.
- 스크립트 언어는 실행 파일을 만들지 않기 때문에, 실행 파일을 만드는 시간이 필요하지 않다.
Node.JS
1. V8
- 자바스크립트엔진으로 빌드된 자바스크립트 런타임 환경
2. Single Thread
3. Non-blocking I/O
ECMAScript
1. JavaScript는 ECMAScript 사양을 준수하는 범용 스크립팅 언어
2. JavaScript는 1996년에 만들어졌고, 그 다음에 JavaScript의 표준화를 위해 1997년에 ECMAScript가 만들어졌다.
3. ECMAScript는 JavaScript를 기반으로 하는 동시에, JavaScript 역시 ECMAScript를 기반으로 한다.
JavaScript
1. 데이터 타입
- 원시 타입
- 숫자
- 문자열
- boolen
- Truthy
- Falsy
- false / undefined / null / 0, -0 / NaN / ''(빈 문자열)
- undefined
- 자바스크립트 엔진이 변수를 초기화하는 데 사용
- null
- 개발자가 의도적으로 변수에 값이 없다는 것을 명시하고 싶을 때 사용
- symbol
- bigint
- 객체 타입
2. 변수
- 변수 종류
- var
- let, const
- let
- const
- 변수 생성 단계
- 선언(Declaration)
- 초기화(Initialization)
- var는 undefined 할당
- let, const는 (Temporal Dead Zone)때문에 할당 불가능
- 할당(Assignment)
3. 함수
- 함수 선언문
function add(x, y) {
return x + y;
}
- 함수 표현식
var add = function(x, y) {
return x + y;
}
- new Function()
var add = new Function('x', 'y', 'return x+y');
- 화살표 함수
var add = (x, y) => x + y;
4. 스코프
- 식별자(변수)나 함수에 접근 가능한 유효 범위를 의미한다.
- 특정 변수나 함수를 어느 위치에서 참소할 수 있는 지를 나타내며 만약 스코프에서 벗어난 위치에서 참조할 경우 Reference Error가 발생한다.
- 스코프의 종류
- 전역 스코프
- 지역 스코프
- 함수 레벨 스코프
- 함수 코드 블록 내에서만 참조(접근) 가능한 범위를 말한다.
- var
- 블록 레벨 스코프
- 코드 블록 ({}) 내에서만 참조(접근)가능한 범위를 말한다.
- let, const, if, for, while, try/catch ...
- 스코프 방식
- 동적 스코프(Dynamic scope)
- 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정한다.
- 정적 스코프(Static scope), 렉시컬 스코프(Lexical scope)
- 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정한다.
- 코드가 작성된 위치에 따라 변수의 유효 범위가 결정된다.
- JavaScript는 렉시컬 스코프를 따른다.
- 스코프 체이닝
scope.js

5. 호이스팅
- 자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다.
- 소스코드 실행을 위한 준비 단계인 소스코드의 평가 과정에서 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다.
- 소스코드의 평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드 한 줄씩 실행한다
- 모든 식별자(변수, 함수, 클래스 등)는 호이스팅된다.
- 변수 호이스팅
- var
- 함수 단위 스코프(function-level scope)
- 호이스팅 발생
- 선언 단계와 초기화 단계가 한번에 진행
- let, const
- 블록 단위 스코프(block-level scope)
- 호이스팅 발생 그러나 변수 선언 이전에 발수 참조 불가능, TDZ(Temporal Dead Zone)
- 선언 단계와 초기화 단계가 분리되어 진행, 초기화 단계는 코드 런타임일 때 초기화 진행
- 함수 호이스팅
- 함수 선언문은 함수 객체로 할당하여 호출 가능
- 함수 표현식은 변수 호이스팅으로 발생
- 클래스 호이스팅
- 호이스팅 발생 그러나 변수의 let, const와 같이 TDZ가 존재하여 런타임 이전에 실행 불가능
6. this
- 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이다.
- this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
- this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

- 일반 함수 호출
- 기본적으로 this에는 전역 객체가 바인딩
- 일반 함수로 호출된 모든 함수(중첩 함수, 콜백 함수) 내부의 this에는 전역 객체에 바인딩
this_1.js
- 메서드 호출
- 매서드 내부의 this는 메서드를 호출한 객체에 바인딩
this_2.js
- 생성자 함수 호출
- 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스 바인딩
this_3.js
- Function.prototype.apply/call/bind 메서드에 의한 간접 호출
7. 프로토타입(prototype)
- 자바스크립트는 프로토타입 객체지향 프로그래밍
- 자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불피요한 중복을 제거한다.
-
프로토타입이 아닌 인스턴스 생성일 때
function Circle(radius) {
this.radius = radius;
this.getArea = function () {
return Math.PI * this.radius ** 2;
}
}
const circle1 = new Circle(1);
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea);

-
프로토타입을 사용한 인스턴스 생성일 때
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getArea = function() {
return Math.PI * this.radius ** 2;
};
const circle1 = new Circle(1);
const circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea);

8. 프로토타입 체이닝

9. 생성자 함수
- ES6 이전에는 자바스크립트에 클래스 문법이 없었고 객체 지향 프로그래밍을 구현하려면 생성자 함수와 프로토타입을 사용해야 했다.
- 생성자 함수는 프로토타입을 직접 사용해 메서드를 정의하기 때문에, 클래스처럼 extends나 super 같은 키워드를 사용할 수는 없으나 객체 생성 시 메모리를 효율적으로 관리할 수 있습니다.
- 함수 정의: 일반 함수처럼 정의하나 관례적으로 첫 글자를 대문자로 작성한다.
- this 키워드: 생성자 함수 내에서 this 키워드는 새로 생성될 객체를 참조한다.
- 속성 및 메서드 추가: this를 사용하여 객체의 속성과 메서드를 정의한다.
- new 키워드 사용: 생성자 함수를 호출할 때는 항상 new 키워드를 사용해야 합니다. 그렇지 않으면 this는 전역 객체를 가리킨다.
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(`이름: ${this.name}, 나이: ${this.age}`);
};
}
const person1 = new Person('가', 30);
const person2 = new Person('나', 40);
person1.sayHello();
person2.sayHello();
10. 클래스
- ES6(ECMAScript 2015)에서 클래스 문법이 도입되었지만, 사실 이 클래스 문법도 생성자 함수와 프로토타입 기반 상속을 단순화한 문법적 설탕(syntactic sugar)일 뿐, 자바스크립트의 근본적인 동작 방식은 여전히 프로토타입 기반이다.
- constructor 메서드를 사용해 객체를 초기화하고, extends로 상속을 구현.
- 사실상 생성자 함수 위에 얹어진 문법적 설탕으로, 클래스도 내부적으로는 생성자 함수처럼 동작함.
- 프로퍼티, 메소드
- constructor, super, extent
- public, private, protect, static
11. 생성자 함수와 클래스 차이
- 클래스 문법을 도입하기 전에는 객체를 생성하고 상속을 구현하기 위해 생성자 함수와 프로토타입을 사용해야 했다.
- 클래스는 이러한 생성자 함수의 복잡성을 숨기고, 개발자에게 좀 더 직관적이고 익숙한 방식으로 객체를 생성하는 방법을 제공한다.
12. 실행 컨텍스트
- 실행 컨텍스트는 소스코드를 실행하는 데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다.
- 실행 컨텍스트는 식별자(변수, 함수, 클래스 드으이 이름)를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 매커니즘으로, 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다.
- 식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고 코드 실행 순서는 실행 컨텍스트 스택으로 관리한다.
- JavaScript는 함수가 실행될 때마다 메모리 상에 실행 컨텍스트를 생성합니다.
var x= 1;
const y = 2;
function foo (a) {
var x = 3;
const y = 4;
function bar(b) {
const z = 5;
console.log(a + b + x + y + z);
}
bar(10);
}
foo(20);

13. 클로저
- 외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 경우 중첩 함수를 클로저라고 한다.
- 외부 함수보다 더 오래 생존한 중첩 함수는 외부 함수의 생존 여부(실행 컨텍스트의 생존 여부)와 상관없이 자신이 정의된 위치에 의해 결정된 상위 스코르픞 기억한다.
- 중첩 함수 inner의 내부에서는 상위 스코프를 참조할 수 있으므로 상위 스코프의 식별자를 참조할 수 있고 식별자의 값을 변경할 수도 있다.
const x = 10;
function outer() {
const x = 20;
const inner = function () {
console.log(x);
};
return inner;
}
const innerFunc = outer();
innerFunc();

- 클로저 활용
- 상태를 안전하게 변경하고 유지하기 위해 사용
- 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용
14. 비동기 프로그래밍
- Ajax
- API
- API(Application Programming Interface)
- 애플리케이션이 어떤 프로그램이 제공하는 기능을 사용할 수 있게 만든 매개체
- REST API
- REST(Representational State Transfer)
- URI로 자원을 표현하는 데에 집중하고, 자원의 상태(행위)에 대한 정의는 HTTP METHOD로 하는 것이 REST한 API를 설계하는 중심 규칙이다.
- URI로 자원(리소스)을 표현해야 한다.
- 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현된다.
15. 프로미스
- callback hell
getData (function (x) {
getMoreData (x, function (y) {
getMoreData (y, function (z) {
getMoreData (z, function (z) {
...
});
});
});
});
- Promise
- Pending(대기)
- Fulfilled(이행)
- Rejected(거부)
- Promise Handler
- then
- Promise 상태가 Fulfilled로 변경되었을 때 실행할 콜백 함수
- catch
- Promise 상태가 Rejected로 변경되었을 때 실행할 콜백 함수
- finally
- Promise 상태 변경에 상관없이 무조건 실행할 콜백 함수
- Promise 체이닝
16. async, await
- Promise 체이닝에 따른 Promise hell에 따른 로직을 간결화
fetch('https://example.com/api')
.then(response => response.json())
.then(data => fetch(`https://example.com/api/${data.id}`))
.then(response => response.json())
.then(data => fetch(`https://example.com/api/${data.id}/details`))
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));