자바스크립트는 브라우저 말고 서버에서도 실행 가능 + JS 엔진이 든 모든 디바이스에서 동작. 브라우저엔 JS 가상머신이라 불리는 엔진이 내장되어있음. 엔진의 종류는 다양하다. (V8: 크롬, 오페라 / SpiderMonkey, Chakra …)
JS 엔진 동작 기본 원리
- 엔진 (브라우저라면 내장 엔진)이 스크립트를 읽는다 (파싱)
- 읽어들인 스크립트를 기계어로 전환 (컴파일)
- 기계어로 전환된 코드가 실행됨. 기계어로 전환되었기때문에 실행 속도가 빠름
엔진은 위 단계마다 최적화를 진행함. 심지어 컴파일이 끝나고 실행중인 코드를 감시하면서, 이 코드로 흘러가는 데이터를 분석하고, 분석 결과를 토대로 기계어로 전환된 코드를 다시 최적화하기도 한다. 이 과정을 통해 스크립트 실행 속도가 더 빨라진다.
브라우저에서 할 수 없는 일: 파일 접근 (브라우저 창에 파일을 끌어다두거나 인풋 태그로 선택하는 등 특정 상황에서만 파일 접근 허용)
브라우저에서 실행 전 트랜스파일할 수 있는 언어들의 예시: 타입스크립트(자바스크립트로 트랜스파일 가능)
프로토타입이란
아래 두 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