TypeScript는 JavaScript의 superset이다. 따라서 JS를 제대로 알아야 TS도 잘 쓸수가 있다. TS에서도 사용되는 JS의 주요 개념 세가지 - Prototype, this, module을 리뷰하고 넘어가자.
JS의 모든 객체는 Prototype 객체를 상속한다.
심지어는 Object 객체(object Object) 또한 Prototype 객체를 부모로 가진다.
var x = {};
var y = {};
// x에는 toString 메소드가 없지만 아래 구문은 동작한다.
console.log(x.toString()); // [object Object]
console.log(x);
console.log(x.__proto__ === y.__proto__); // true
예를들어 위 코드를 보면, 우리가 정의한 x 객체 안에는 toString 메소드가 없다. 하지만 작동한다.
이게 가능한 이유는 x 객체가 자동으로 Object prototype 객체를 부모로 두고 있고, 이 부모의 toString 메소드를 상속받고 있기 때문이다.
실제로 x를 console.log 해보면 내부에 아래와 같이 Object prototype 객체를 가지고 있고, 그 안에 toString 메소드를 포함하고 있는 것을 확인할 수 있다.

마지막으로 위 코드의 마지막 줄을 보자. 해당 표현식의 결과값은 true인데, 이것을 통해 우리는 각 Object 인스턴스인 x, y가 같은 Object prototype을 상속하고 있다는 것을 확인할 수 있다.
__proto__의 의미?
[[Prototype]]의 값은 Prototype(프로토타입) 객체이며 proto accessor property로 접근할 수 있다. proto 프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf가 호출되어 프로토타입 객체를 반환한다. ⇒ 즉 프로토타입 객체에 접근하기 위한 accessor property로서 __proto__를 사용한다고 볼 수 있다.
const array = [];
console.log(array);



array instance를 생성했기 때문에 우리가 자유롭게 배열의 메소드들을 사용할 수 있는 것이다.// function으로 생성자 함수(클래스 역할) 정의
function CoffeeMachine(beans) {
this.beans = beans;
// Instance member level
this.roastBeans = (grams) => {
console.log('roasting...');
};
}
// Prototype member level
CoffeeMachine.prototype.makeCoffee = (shots) => {
console.log('making...');
};
// new 키워드로 인스턴스 생성
const machine1 = new CoffeeMachine(10);
console.log(machine1);
machine1.roastBeans(1);
machine1.makeCoffee(1);
function LatteMachine(milk) {
this.milk = milk;
}
// Inheriting CoffeeMachine
LatteMachine.prototype = Object.create(CoffeeMachine.prototype);
const latteMachine1 = new LatteMachine();
console.log(latteMachine1);
latteMachine1.makeCoffee(1);

roastBeans의 경우 인스턴스 레벨(this객체를 통해 정의),makeCoffee의 경우 프로토타입 레벨로 정의되어 있다. (.prototype 프로퍼티를 통해 정의).을 통해 사용할 수 있다.