var의 첫 번째 문제는 정의된 변수가 함수 스코프를 가진다는 것이다.
var는 함수 스코프 이기 때문에 함수를 벗어난 영역에서 사용하면 에러가 발생한다.

함수 안에서 var 키워드를 사용하지 않고 변수에 값을 할당하면 그 변수는 전역 변수가 된다.

for 반복문에서 정의된 변수가 반복문이 끝난 이후에도 계속 남는다는 문제점이 있다.
for문, while문, switch문, if문 등 함수 내부에서 작성되는 모든 코드는 같은 문제가 있다

var 변수의 스코프를 제한하기 위해 즉시 실행 함수를 사용하기도 한다.
하지만 즉시 실행 함수는 작성하기 번거롭고 가독성도 떨어진다.
호이스팅이란 var로 정의된 변수는 그 변수가 속한 스코프의 최상단으로 끌어올려지는 것을 말한다.
변수를 정의 하기전에 사용했음에도 코드를 실행하면 에러가 발생하지 않는 문제가 생긴다.



var를 이용하면 한번 정의된 변수를 재정의 할 수 있다.
변수를 정의 한다는 것은 이전에 없던 변수를 생성한다는 의미로 통용된다.
변수가 재정의 될 수 있다는 것은 직관적이지 않으며 버그로 이어질 수 있다.


또다른 문제는 var가 재할당 가능한 변수로 밖에 만들 수 없다는 점이다.
상수처럼 무조건 쓸 값도 무조건 재할당 가능한 변수로 만들어야한다.
블록 스코프에서 블록 안에서 정의 된 변수는 블록 안을 벗어나면 참조할 수 없다.


const 또는 let으로 정의된 변수도 호이스팅되지만 변수를 정의하기 전에 그 변수를 사용하려고 하면 참조 에러가 발생한다.

임시적 사각지대란 변수가 정의된 위치와 호이스팅된 위치 사이를 말한다.
정의된 위치와 호이스팅된 위치 사이에서 변수를 사용하려고 하면 에러가 발생한다.

const로 정의된 변수는 재할당이 불가능하다.
하지만 let, var로 정의된 변수는 재할당 가능하다.
재할당 불가능한 변수는 프로그램의 복잡도를 낮춰 주기 때문에 되도록이면 const를 사용하는게 좋다.
재할당 불가능한 변수:
객체의 내부 속성값도 수정 불가능하게 만들고 싶다면 immer, immutable.js등의 외부패키지를 활용하는 것이 좋다. => 외부 패키지는 객체를 수정하려고 할 때 기존 객체를 변경하지 않고 새로운 객체를 생성
새로운 객체를 생성하는 편의 기능은 필요 없고 단지 수정만 할 수 없도록 차단하고 싶다면 자바 스크립트 내장 함수를 이용하면 된다.



단축속성명은 객체 리터럴 코드를 간편하게 작성할 목적으로 만들어진 문법

새로 만들려는 객체의 속성값 일부가 이미 변수로 존재하면 간단하게 변수이름만 적어주면 된다.
(속성명은 변수 이름과 같아진다.)
속성값이 함수이면 function 키워드 없이 함수명만 적어도 된다.(속성명은 함수명과 같아진다.)


계산된 속성명은 객체의 속성명을 동적으로 결정하기 위해 나온 문법이다.
계산된 속성명은 컴포넌트의 상탯값을 변경할 때 유용하게 쓸 수 있다.

전개 연산자는 배열이나 객체의 모든 속성을 풀어놓을 때 사용하는 문법으로 매개변수가 많은 함수를 호출할 때 유용하다.
전개 연산자를 사용하면 동적으로 함수의 매개변수를 전달할 수 있다.


배열 리터럴에서 중간에 전개 연산자를 사용하면 전개 연산자 전후의 순서가 유지된다

전개 연산자를 이용하면 서로 다른 두 배열이나 객체를 쉽게 합칠 수 있다.

중복된 속성명 사용 시 최종 결과는 마지막 속성명의 값이 된다.
중복된 속성명과 전개 연산자를 이용하면 객체의 속성값을 변경할 때 이전 객체에 영향을 주지 않고 새로운 객체를 만들어 낼수 있다. => 수정 불가능하도록 관리할 때 사용

배열 비구조화는 배열의 여러 속성값을 변수로 쉽게 할당할 수 있는 문법
새로운 변수로 할당할 수 있고 이미 존재하는 변수에 할당할 수도 있다.

배열의 속성값이 undefined라면 정의된 기본값이 할당되고, 그렇지 않으면 원래의 속성값이 할당된다.

두 변수가 값을 교환할 때 배열 비구조화를 사용하면 된다.

배열에서 일부 속성값을 무시하고 진행하고 싶다면 건너뛰는 개수만큼 쉼표를 입력하면 된다.

배열의 비구조화시 마지막에 ...와 함께 변수명을 입력하면 나머지 모든 속성값이 새로운 배열로 만들어진다.
나머지 속성값이 존재하지 않으면 빈 배열이 만들어진다.

객체 비구조화는 객체의 여러 속성값을 변수로 쉽게 할당 할 수 있는 문법이다.
객체 비구조화는 중괄호를 사용하고 배열 비구조화와는 다르게 순서는 무의미하다.
객체 비구조화는 기존 속성명을 그대로 사용해야 한다.



객체 비구조화에서는 속성명과 다른 이름으로 변수를 생성할 수 있다. => 중복된 변수명을 피하거나 좀더 구체적인 변수명을 만들 때 좋다.
속성명 age의 값을 theAge에 할당했기 때문에 age를 출력할시 참조에러가 발생합니다.

객체 비구조화에서도 기본 값을 정의할 수 있고 속성값이 undefined이면 기본값이 들어가고, null이면 기본값은 들어가지 않는다.

기본값을 정의 하면서 별칭을 함께 사용할 수 있다.

기본값으로 함수의 반환값을 넣을 수 있다
기본값이 사용될 때만 함수가 호출된다.

객체 비구조화에서도 사용되지 않은 나머지 속성들을 별도의 객체로 생성할 수 있다.

for문에서 객체를 원소로 갖는 배열을 순회할 때 객체 비구조화를 사용하면 편리하다.

비구조화는 객체와 배열이 중첩되어 있을 때도 사용할 수 있다.
=> 비구조화 결과로 motherName이라는 변수만 생성되기 때문이다.
비구조화에서 기본값의 정의는 변수로 한정되지 않는다.
=>첫번째 원소가 존재하지 않아서 기본값이 할당된다.
배열의 첫번째 원소가 존재하므로 기본값이 할당되지 않는다.

객체 비구조화에서도 계산된 속성명을 활용할 수 있다.
객체 비구조화에서 계산된 속성명을 사용할 때에는 반드시 별칭을 입력해야한다
별칭은 단순히 변수명만 입력할 수 있는 것은 아니다


입력값이 undefined인 경우에만 기본 값이 적용된다


매개변수값이 없으면 required함수에서 예외가 발생하기 때문에 매개변수 a는 필숫값이 된다.

나머지 매개변수는 입력된 인수 중에서 정의된 매개변수 개수만큼을 제외한 나머지를 배열로 만들어준다=> 매개변수 개수가 가변적일 때 유용
ES5에서의 arguments 키워드와 비슷한 역할을 한다.

arguments의 존재가 명시적으로 드러나지 않기 때문에 가독성이 좋지 않다.
arguments는 배열이 아니기 때문에 배열처럼 사용하기 위해서는 배열로 변환하는 과정이 필요하다는 단점이 있다.

명명된 매개변수는 객체 비구조화를 이용해서 구현할 수 있다.
함수 호출시 매개변수의 이름과 값을 동시에 적을 수 있으므로 가독성이 높다

명명된 매개변수를 이용하면 선택적 매개변수의 활용도가 올라간다.
선택적 매개변수란 필숫값과 반대되는 의미로 있어도 되고 없어도 되는 매개변수를 말한다.
필요없는 매개변수 자리에 undefined를 넣으면 된다. => 이 방법은 매개변수 갯수가 많아지면 관리하기 힘들어진다.

명명된 매개변수를 사용하면 함수를 호출할 때마다 객체가 생성되기 때문에 비효율적일 것이라고 생각할 수 있지만 자바스크립트 엔진이 최적화를 통해 새로운 객체를 생성하지 않으므로 안심하고 사용해도된다.
화살표 함수를 이용해 함수를 간결하게 작성할 수 있다.

화살표에 여러줄의 코드가 필요하다면 전체를 중괄호로 묶고 반환값에는 return 키워드를 사용한다.

화살표 함수는 this와 arguments가 바인딩되지 않는다.
화살표 함수에서 arguments가 필요하다면 나머지 매개변수를 이용해야한다.

일반 함수에서 this는 호출 시점에 사용된 객체로 바인딩이 된다.
객체에 정의된 일반 함수를 다른 변수에 할당해서 호출하면 버그가 발생할 수 있다.

생성자 내부에서 정의된 화살표 함수의 this는 생성된 객체를 참조한다

=> setInterval 함수의 인수로 들어간 increase함수는 전역환경에서 실행되기 때문에 this는 window 객체를 참조해서 obj.value는 증가하지 않는다

클로저

