자바스크립트는 브라우저 말고 서버에서도 실행 가능 + JS 엔진이 든 모든 디바이스에서 동작. 브라우저엔 JS 가상머신이라 불리는 엔진이 내장되어있음. 엔진의 종류는 다양하다. (V8: 크롬, 오페라 / SpiderMonkey, Chakra …)

JS 엔진 동작 기본 원리

  1. 엔진 (브라우저라면 내장 엔진)이 스크립트를 읽는다 (파싱)
  2. 읽어들인 스크립트를 기계어로 전환 (컴파일)
  3. 기계어로 전환된 코드가 실행됨. 기계어로 전환되었기때문에 실행 속도가 빠름

엔진은 위 단계마다 최적화를 진행함. 심지어 컴파일이 끝나고 실행중인 코드를 감시하면서, 이 코드로 흘러가는 데이터를 분석하고, 분석 결과를 토대로 기계어로 전환된 코드를 다시 최적화하기도 한다. 이 과정을 통해 스크립트 실행 속도가 더 빨라진다.

브라우저에서 할 수 없는 일: 파일 접근 (브라우저 창에 파일을 끌어다두거나 인풋 태그로 선택하는 등 특정 상황에서만 파일 접근 허용)

브라우저에서 실행 전 트랜스파일할 수 있는 언어들의 예시: 타입스크립트(자바스크립트로 트랜스파일 가능)

프로토타입이란

아래 두 doSomething() 메서드의 차이가 뭘까?

Array.doSomething()
Array.prototype.doSomething()

여기서 위의 doSomething() 메서드는 Array 클래스에서만 작동하고, 아래 메서드는 Array 인스턴스에서만 작동한다.

let arr = [1,2,3,4]; // arr is an instance of Array
let arr = new Array(1,2,3,4);

위 코드에서 arr은 자바스크립트 배열의 인스턴스다. 위 아래 똑같다.
객체지향 프로그래밍에서는 클래스라는 틀을 기반으로 인스턴스(하나의 예시)들을 만들기 때문에 배열 하나를 만들때는 new Array()를 사용해서 만들어주면 된다.

JS의 프로토타입

자바스크립트는 프로토타입 기반 언어다. 프로토타입을 사용해 객체지향 프로그래밍을 흉내낸다. 이 때 프로토타입은 원형을 뜻한다. 인스턴스는 원형의 모양대로 만들어진다. 인스턴스 === 원형이 아님에 주의하도록 하자. 자바스크립트에서 인스턴스의 메서드는 Object.prototype.doSomething()으로 표현한다. ES6 문법에서는 문법을 좀 더 편리하게 하기 위해 'class'라는 키워드를 도입하였다.

클래스

function Car(model, brand) {
    this.model = model;
    this.brand = brand;
}
    
let spark = new Car("스파크", "쉐보레");
let avante = new Car("아반떼", "현대");

Car.prototype.ride = function() {
    console.log(`${this.model}이 달립니다`)
};

클래스와 객체의 차이는 뭘까?

클래스

  • 조금 더 연관있는 데이터를 한 데 묶어놓는 컨테이너이자 템플릿, 즉 붕어빵 틀이다.
  • 처음 한번만 선언하고 데이터(붕어빵 반죽, 팥)는 들어있지 않다.
  • 데이터(fields)와 행동(methods)를 담아 캡슐화를 해 상속과 다형성 등의 특성을 가진다.

객체

  • 클래스에 데이터를 넣어 만든 인스턴스를 객체라고 한다. 붕어빵 틀에 반죽을 넣고 만든 팥붕 슈붕이 객체인 셈이다.

프로토타입 확장하기

Number.prototype.multiplyTen = function() {
    return this * 10
}

let num = 5;
num.multiplyTen(); // 10

위 방식으로 자바스크립트에서 기본으로 제공하는 객체에 사용자 정의 메소드를 개발자가 직접 추가할 수 있다. 그러나 좋은 방식은 아니다. 메서드를 확장할 경우 다른 코드와 충돌을 일으킬 수 있다. 직접 클래스를 작성할 때에만 프로토타입 메서드를 정의하는게 좋다.

JS Tips

  • var는 정의되기 전에 접근할 수 있지만 그 값에는 접근 불가능
  • let, const는 정의하기 전에 접근 불가
  • 호이스팅: 모든 변수가 실행전 범위 내 상단으로 올라감. var는 정의되기 전에는 undefined, let은 변수가 선언될까지는 TDZ(Temporal Dead Zone비활성구역)에 있어서 오류가 발생
  • 기본적으로 const 사용하자. 재할당 필요할 때만 let 사용하자. Var는 ES6에서 절대 사용X
  • 디스트럭처링: 배열의 값 또는 객체의 속성을 풀어서 별개의 변수로 쓸 수 있게 하는 JS 표현식
  • JS도 제너레이터 있음

반복문

  • For of 루프/ 객체는 iterable이 아니니까 Object.keys()로 값 가져와서 for of 루프 돌리면 됨
  • for in 루프는 순서 없이 객체의 모든 iterable props를 반복. for in 루프는 키 목록을 반환함

Array 함수

- Array.from() 객체를 배열로 받아서 변환(html elements 받아오기 유용)
- Array.from('apple')하면 [a,p,p,l,e]
- Array.of() 전달받은 인수로 배열생성

스프레드 문법

: 배열 복사본 만들 때 매우 유용

const veggie = [1, 2];
const meat = [4, 5];
const menu = [...veggie, 3, ...meat];
// menu = [1,2,3,4,5]

Rest 문법

: ...로 특정한 놈들만 빼고 압축해줌

const runners = [1, 2, 3, 4];
const [first, second, ...losers] = runners;
console.log(losers); // 3,4