# Short-circuit evaluation 활용하기

활용.

/* 함수 인수 디폴트 값 */
function stub(foo) {
    return foo || "default value";
}

function stub(foo = "default value";) { // ES6
}

/* 조건부 호출 */
var age = 20;
age >= 18 && console.log("참일때 호출된다");
age >= 18 || console.log("거짓일때 호출된다");

function fn(cb) {
    cb && cb(); // 함수가 제공될 때만 함수 호출
}

# 화살표 함수

var that = this;
button.addEventListener("click", function() {
    that.onClick(); // 크로스-커팅 문제: 외부에 핸들러를 바인딩하거나 클로저를 통해 변수로 전달해야함
});

button.addEventListener("click", () => {
    this.onClick(); // 화살표 함수 쓰면 자신의 컨텍스트를 생성하는 대신 주변 객체의 컨텍스트를 사용 가능
    });

# 메서드 정의

var foo = {
    bar: function(a, b) { // 기존
    }
}

let foo = {
    bar (a, b) { // ES6에선 함수 키워드와 콜론을 제거 가능
    }
}

# 나머지 연산자(rest operator)

let cb = function(a, b, ...args) {
    console.log(a, b, args);
}
cb("foo", "bar", 1, 2, 3); // foo bar [1, 2, 3]

let [bar, ...others] = ["bar", "foo", "baz", "qux"];
console.log([bar, others]); // ["bar", ["foo", "baz", "qux"]]

# 펼침 연산자

let args = [2015, 6, 17];
let relDate = new Date(...args); // 배열 요소를 인수로 확산 가능

# 템플릿 리터럴

멀티라인 문자열은 js에서 사용하기 힘들었음. ES6에 Template literal 도입되고 편해짐.

var foo = "hi";
var str = `첫번째 줄 \n
두번째 줄 \n
변수 참조 가능: ${foo}
`

# ES6의 배열 메서드

/* 배열 채우기 */
var arr = Array(3);
console.log(arr.fill("foo")); // ["foo","foo","foo"]

/* 배열에 인자 있나 검사 */
arr.includes("foo"); // arr.indexOf(val) !== -1 과 동일

/* 배열 찾기 */
arr.find(val => {
    return val.length < 3; // Array.prototype.filter는 배열이나 null을 반환하고 이건 하나의 요소를 반환
});

# 객체 탐색하기

for(key in options) {
    console.log(key, options[key]); // 이러면 객체 prototype에 있는것까지 for문을 돌고 말아부려. 그래서 Object.proptotype.hasOwnProperty메서드로 해결했어야 했다.
}

Object.keys(options).forEach(key => {
    // 이러면 나 자신만의 문자열 키-값만 검색함. 성능도 더 좋다.
    });

# 배열 같은 객체의 열거

arguments나 nodeList(node.querySelectorAll, document.forms)같은 객체는 배열처럼 보이지만 실제로는 배열이 아님. 배열과 유사하게 length속성 가지며 for루프로 반복할 수 있지만 배열 조작 메서드(map 등)을 지원 안 함.

var nodes = document.querySelectorAll("div");
var arr = Array.prototype.slice.call(nodes); // 배열 변환법 1
var arr = [].slice.call(nodes); // 배열 변환법 2
var arr = Array.from(nodes); // 배열 변환법 3

# ES6의 컬렉션

구문이 클래스 기반처럼 보이지만, 사실은 기존 프로토타입의 신택틱 슈거다.

class ConcreteClass extends AbstractClass {
    constructor() {
        super();
        this.bar = 3;
    }
    baz() {
        return "baz";
    }
}
let instance = new ConcreteClass();
instance.bar; // 3
instance.baz(); // baz

# 돔 스크립팅과 AJAX

  • document.querySelector('#bar')로 발견된 요소는 NodeList로 표현된다. 배열처럼 보이지만 실제 배열은 아님. DOM이 리플로(reflow)될 때마다 업데이트되는 라이브 콜렉션.
    • 라이브 콜렉션(NodeList.HTMLCollection)에서의 반복은 느리며 상당히 비싼 자원 소비한다. 따라서 콜렉션이 라이브일 필요 없을땐 [].slice.call(NodeList)와 같은 배열로 변환한다. ES6에선 [...nodeList]spread연산자를 사용해 수행 가능
var lis = document.querySelector('.class');
foo = [].slice.call(lis); // ES5방식 배열 변환
foo = [...lis]; // ES6방식 배열 변환
  • el.innerHTML을 변경하거나 요소에 자식을 추가할 때마다 DOM리플로가 발생한다. 리플로가 반복적으로 발생하면 애플리케이션이 느려진다.
    • 브라우저는 el.innerHTML로 HTML을 처리할 때 문자열을 먼저 파싱해야 한다. 이는 자원을 많이 소모하는 작업. 그러나 명시적으로 요소 생성보단 훨 빠름.
    • 유사한 요소를 배치(batch)로 만들면, 처리는 더 최적화 가능.
    • 루프에서 모든 요소를 생성하는 대신 원본에서 복제(el.cloneNode)하면 더 빨라지게 할 수 있다.

# DOM 스타일링

  • 스타일이 필요할 땐 가능한 한 CSS클래스 사용하는게 좋다. 이는 상속 및 구성, 분리와 같은 더 좋은 유지보수 제공.
el.classList.add('is-hidden');
el.classList.remove('is-hidden');
el.classList.toggle('is-hidden', !isAvailable);
if(el.classList.contains('is-hidden'))