[1] 프로토타입 기반 언어
1. 프로토타입과 생성자 함수
객체지향 프로그래밍
- 객체는 현실의 개념을 추상화하여 정의
- 상태를 갖고 있고 → this
- 식별자(속성)을 갖고 있고 → 속성
- 어떠한 행동을 갖고 있음 → 메서드
- 인스턴스 객체
- 객체지향 프로그래밍 :
- 객체라는 기본 단위로 나누고, 이들의 상호작용으로 서술하는 방식
- 대표적인 객체지향 프로그래밍
- 클래스 기반 객체지향 → 자바, ...
- 프로토타입 기반 객체지향 → 자바스크립트, ... ✔
- 프로토타입 객체
- 객체의 인스턴스를 만드는 부모 객체 개념
- 자바스크립트의 모든 객체는 부모 객체인 프로토타입 객체와 연결
- 부모 객체의 속성과 메서드를 상속받아 사용 가능
프로토타입 객체 - 접근하기
- 모든 객체가 갖고 있는 [ [Prototype] ] 인터널 슬롯
- [ [Prototype] ]은 상속을 위해 사용
- __proto__라는 접근자 속성으로 접근 가능
- __proto__로 Object.prototype 객체에 접근
프로토타입 객체 - 생성하기
- 함수타입에만 존재하는 prototype 필드
- 함수에 부모객체 존재
- 함수를 활용하여 → 부모객체의 인스턴스 생성 가능
- 생성자 함수
- 인스턴스 객체 생성시 사용
- 대문자 함수명 컨벤션
- new 키워드와 함께 호출
- 인스턴스의 부모 객체 == 생성자 함수.prototype
- constructor : 자기 자신을 생성한 객체 참조

2. 프로토타입 chain과 상속
프로토타입 chain
- 객체의 속성 참조시, 속성이 없는 경우 프로토타입 체인 동작
- [ [Prototype] ]을 통해서 부모 객체를 탐색
- 모든 객체의 부모는 Obejct.prototype
- End of prototype chain 프로토타입 체인의 종점
- 만약 마지막 부모 객체 (Object.prototype)에서까지 속성을 찾지 못할 경우, undefined 반환

프로토타입 객체의 확장과 상속
- prototype 객체 속성과 메서드 정의시
- 객체와 프로토타입에 동일한 이름의 속성이나 메서드가 있는 경우
- 객체의 속성이 먼저 참조
- property shadowing : 프로토타입 속성이 가려지는 현상
- method overriding : 프로토타입 메서드가 가려지는 현상
3. class 문법
ES6+ class
- ES6에 calss 문법 추가됨
- 클래스 기반 언어에 익숙한 개발자가 빠르게 학습할 수 있도록
- 기존 프로토타입 기반 상속 매커니즘의 추상화
class의 형태
- class 클래스명 { ... }
- class 내에서는 메서드만 작성 가능
- 인스턴스 생성
class 클래스명 {
...
}
new 클래스명();
class의 문법
- constructor 특수 메서드
- method
- 인스턴스 속성
- 클래스 상속
class의 문법 - constructor
- 인스턴스가 생성하고, 클래스 필드를 초기화하기 위해 약속된 특수 메서드
- 인스턴스 생성시 전달할 인자를 constructor 메서드의 인자로 받을 수 있음
- constructor은 생략 가능
class Person {
constructor(name) {
console.log(name);
}
}
new Person('Joy');
class의 문법 - 인스턴스 method
- 클래스 내에 존재하는 method
- method 내에서 클래스를 this로 접근 가능
- 클래스의 인스턴스 속성에도 접근 가능
class Person {
setName(name) {
console.log(this);
this.name = name;
}
}
const Joy = new Person();
Joy.setName('Joy');
Joy.name;
class의 문법 - 정적 메서드
- 클래스의 인스턴스를 생성하지 않아도 호출할 수 있는 메서드를 정의할 때 사용
- static 키워드 사용
- util용의 함수를 정의할 때 사용
class Person {
constructor(age) {
this.age = age;
}
static legCount() {
return 2;
}
}
Person.legCount();
class의 문법 - 인스턴스 속성
- 클래스 내부에 캡슐화된 변수 == 멤버 변수
- this에 추가한 속성
- 인스턴스 속성은 this에 바인딩 필요
- 속성은 인스턴스 생성 이후 바로 참조 가능해야하므로, 인스턴스 속성 초기화는 constructor 메서드에서 보통 진행
class Person {
constructor(name) {
this.name = name;
}
}
const Joy = new Person('Joy');
Joy.name;
class의 문법 - 인스턴스 속성 조회 및 조작
- getter
- 특정 인스턴스 속성을 조회하며 조작하는 메서드
- 형태
- 메서드 이름 앞에 get 키우드 사용
- getter 메서드는 무조건 값을 반환
- 사용 시,
- 일반 메서드처럼 호출하지 않고
- 속성처럼 참조하는 형식으로 사용
class의 문법 - 상속 - extends
- 코드의 재사용 관점에서 상속 필요 (부모 - 자식)
- extends와 super 키워드를 통해 class에서 상속 구현
- extends
- 부모 클래스를 상속받는, 자식 클래스를 정의할 때 사용
class 부모 {...}
class 자식 extends 부모 {...}
class의 문법 - 상속 - super 키워드
- super()
- 부모 클래스의 생성자를 호출하게 됨
- 부모 클래스의 인스턴스 속성을 바인딩 당함
- 자식 클래스의 생성자가 this에 접근하고 수정 가능
- 자식 클래스에서 constructor 사용시 constructor 반환문 전에 사용되어야 함
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, legCount) {
super(name);
}
sleep() {
return this.name + ' z... ';
}
}
const dog = new Dog('pepe');
dog.name;
dog.sleep();
-> 결과
[2] 자바스크립트 컨텍스트
1. this와 화살표 함수
this란?
- 컨텍스트 참조 가능한 키워드 (전역 Context, 함수 Context)
- 객체를 참조하는 역할, 어떤 객체인지 동적으로 결정됨
- 함수 Context
- 함수가 호출될 때, 매개변수로 this가 암묵적으로 전달
- 함수 호출방식에 따라 this에 바인딩되는 객체가 상이
- ES6 화살표 함수 : this 바인딩을 제공하지 않음
- 함수 호출 방식:
- 함수 호출, 객체의 메서드 호출, 생성자 함수 호출, apply, call, bind로 호출
this 바인딩 - 함수 호출 방식
- 전역객체에서 this 사용시
- Browser-side : window
- Server-side : global
- 함수 내부에서 this는 전역객체에 바인딩
- 함수에 내부함수 존재시에도 this는 전역객체에 바인딩
- 객체의 메서드 내에 내부 함수가 있을 경우, 함수 호출 방식으로 취급되어 전역객체를 바라봄
- 이를 해소하기 위해
- this를 다른 변수에 저장하고 사용하거나
- 내부 함수를 해당 객체에 bind

const foo = {
name: 'joy',
age: 28,
getName() {
const that = this;
function getAge() {
console.log(that.age);
}
getAge();
},
};
foo.getName();
this 바인딩 - 객체 메서드 호출 방식
- 메서드의 내부의 this는 해당 메서드를 호출한 객체에 바인딩
- 프로토타입 객체의 메서드도 동일하게 해당 메서드를 호출한 객체에 바인딩
this 바인딩 - 생성자 함수 호출 방식
- 빈 객체 생성, this 바인딩
-> this는 빈 객체에 바인딩
- this로 속성 생성
-> this를 사용하여 동적으로 속성과 메서드 생성
- 생성된 객체 반환
-> 반환문이 없어도, 1번에서 생성되었던 객체가 반환됨
function Person(name) {
this.name = name;
}
const foo = new Person('joy');
foo.name
this 바인딩 - apply, call, bind 호출 방식
- this를 명시적으로 바인딩 하는 방법
- Function.prototype.apply
- Function.prototype.call
- Function.prototype.bind
this 바인딩 - apply, call
- 함수명.apply(바인딩할 객체, [함수 호출시 넘기는 인자들])
- 함수명.call(바인딩할 객체, 함수 호출 시 넘기는 인자1, ...)
- 함수 내의 this에 바인딩할 객체가 바인딩됨
- 함수에 인자들이 전달됨
- 함수 호출됨
this 바인딩 - bind
- 함수 내의 this에 바인딩할 객체가 바인딩됨
- 바인딩된 함수 반환
-> apply와 차이점 : 바인딩과 함수 호출이 분리
this 바인딩 - 화살표 함수
- ES6의 화살표 함수
- 함수를 선언할 때, this에 바인딩할 객체가 정적으로 결정
- 항상, 상위 스코프 this를 가리킴 (Lexical this)
- 화살표 함수의 형태 : 익명함수 형태
- 지양해야 하는 사용 형태
- 객체의 메서드 ( + prototype 메서드 )
- 생성자 함수 : prototype 객체 없음
const foo = {
name: 'joy',
age: 28,
getName: () => {
console.log(this.name);
},
};
foo.getName();
2. scope
프로그래밍에서 Scope
- 스코프 == 변수 영역
- 변수가 유효성을 갖는 영역
- 스코프의 규칙
- 렉시컬 스코프 규칙, dynamic 스코프 규칙
- 스코프의 종류
- 전역, 모듈, File, 함수, 블록, ...
Scope의 규칙 - lexical scoping rule
- 정적 영역 규칙 static scoping rule (lexical scoping rule)
- 어디서 호출하였는지가 아니라, 어디에서 선언하였는지에 따라 스코프 결정 (소스코드 구조 기준)
- 자바스크립트는 lexical scoping rule을 따름
Scope의 규칙 - dynamic scoping rule
- 동적 영역 규칙 dynamic scoping rule
- 어디에서 호출하였는지에 따라 스코프 결정
- 런타임때 결정됨
Scope의 종류
- 전역 스코프 : 소스 코드상의 모든 곳에서 사용할 수 있는 전역 변수
- 자바스크립트 : (브라우저 기준) window 객체
- file 스코프
- 해당 파일 전체에서 접근 가능, 다른 파일에서 접근 불가능
- 원시적인 형태의 모듈 영역
- ES6+ 자바스크립트 : <script type="module" ...>로 조회되는 파일
- 모듈 스코프
- 모듈을 지원하는 프로그래밍 언어에서 모듈 단위의 변수 선언 가능
- 함수 레벨 스코프
- 지역변수 : 함수 내에서 유효한 변수
- 함수가 반환된 이후에는 사용 불가능
- 함수 외부에서 유효하지 않음
- 자바스크립트는 기본적으로 함수 레벨 스코프
- 블록 레벨 스코프
- 지역변수 : 코드 블럭 내에서 유효한 변수
- ES6+ 자바스크립트 : let, const 키워드는 블록 레벨 스코프
자바스크립트의 Scope
- 스코프 규칙 : lexical scoping rule
- 스코프 종류
- 함수레벨 스코프 기반
- 전역 스코프 : 전역 객체 window의 속성(브라우저 기준)
- ES6+ 부터 지원하는 스코프
- 블록레벨 스코프 : let, const 키워드는 블록 레벨 스코프
- file 스코프 : <script type="module" ...>로 조회되는 파일
3. 실행 컨텍스트
자바스크립트를 실행하기 위한 정보


실행 컨텍스트의 생성 단계 - Creation Phase
-> 코드 평가 단계 Lexical Environment 생성
- 함수와 변수를 기록 (Environment Record)
- 선언 정의, 객체 정의
- this 바인딩 : 함수의 호출 여부에 따라 달라짐
- 외부 환경 참조 (Outer Environment Record)
실행 컨텍스트의 생성 단계 - Execution Phase
- 변수는 값이 할당
- 함수 실행 코드가 있을 경우, 함수 실행
- 새로운 함수 실행 컨텍스트 생성 및 함수 실행
실행 컨텍스트의 3가지 종류
- global 컨텍스트 == 전역 컨텍스트
- 함수 내에서 실행되는 코드가 아니라면, 전역 컨텍스트에서 실행
- e.g.브라우저 기준 : Global object = window
- function 컨텍스트
- 함수가 호출될 때마다, 함수에 대한 실행 컨텍스트 생성
- 각 함수들은 자신만의 실행 컨텍스트 존재
- eval 컨텍스트
- eval 함수만의 실행 컨텍스트 존재

자바스크립트의 Call Stack
: 자바스크립트 엔진이 호출된 함수와 순서를 추적하는 방법
- 어떤 함수가 동작하고 있는지, 다음에 어떤 함수가 호출되어야하는지 등을 제어
- 함수가 반환된 후 실행이 올바른 지점에서 다시 선택되도록 함
-> ==함수 호출을 수행할 수 있게 해주는 Record 보관 구조
- stack 자료구조 : 프레임이 쌓이는 Last in First out(LIFO) 형태의 자료구조
- 콜 스택 : 함수 호출 시 만들어지는 실행 컨텍스트가 쌓임
자바스크립트의 엔진은
코드를 평가하여 실행 컨텍스트를 만들어 → 콜스택에 하나씩 쌓고
콜 스택에서 실행 컨텍스트를 실행하며 → stack에서 하나씩 없앰
4. 클로저
함수가 종료되었는데, 아직 참조가 남아있는 경우
- 자바스크립트 : 일급 객체
- 함수 내의 내부 함수
- 발생 조건
- 외부(outer) 함수 실행 컨텍스트 환경의 변수를 참조하고 있는
내부(inner) 함수 실행 컨텍스트
- 상황
- 내부 함수 내에서 아직 외부 함수의 변수를 참조하고 있어,
외부(outer) 함수가 종료되었지만,
외부 함수의 참조가 유지되어, 외부 함수 환경에 접근할 수 있는 상황
클로저
- 반환된 내부함수가
자신이 선언됐을 때의 환경인 스코프를 기억하여
자신의 선언됐을 때의 환경 밖에서 호출되어도
그 환경(스코프)에 접근할 수 있는 함수
클로저의 특징
- 함수가 종료되어도 스코프를 기억
- 특정 스코프에 접근할 수 있는 함수
- 상태 은닉
- 은닉화