모던 자바스크립트 Deep Dive 7~11장 공부
7장 연산자
연산자는 하나 이상의 표현식을 대상으로 산술 할당, 비교, 논리, 타입, 지수 연산 등을 수행해 하나의 값을 만든다.
- 연산의 대상을 피연산자라고 한다.
- 피연산자는 값으로 평가될 수 있는 표현식 이어야 한다.
- 표현식은 값으로 평가될 수 있는 문
- 2개의 피연산자를 산술 연산하여 숫자값을 만든다.
- +, - , * , / , %
단항 산술 연산자
- 1개의 피연산자를 산술하여 숫자 값을 만든다.
- ++, --, +, -
- 증감, 감소는 위치에 의미가 있다.
- + 연산자는 피연산자 중 하나 이상이 문자열일 경우 문자열 연결 연산자로 동작한다.
- '1' + 1 -> 11
- '1' + true ->2
- '1' + false -> 1
- 자바스크립트 엔진에서는 개발자와의 의도와 상관없이 암묵적으로 타입 변환이 일어난다. 이것을 암묵적 타입변환이라고 한다.
할당 연산자
- 우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당한다.
- =, += , -+, /=, %=
동등, 일치 비교 연산자
- 자바스크립트 엔진에서는 개발자와의 의도와 상관없이 암묵적으로 타입 변환이 일어난다.
- 동등 비교 연산자는 좌항과 우황의 피연산자를 비교할 때 먼저 암묵적 타입 변환을 통해 타입을 일치시킨 후 값인지 비교한다.
- 동등 비교 연산자는 좌항과 우황의 피연산자 타입이 다르더라도 암묵적 타입 변환을 한후 같은 같을 낼 수 있다면 true를 반환
- 동등 비교 연산자는 여측하기 어려운 결과를 만들어 낼 수 있기 때문에 일치 비교 연산자 사용을 지양한다.
삼항 조건 연산자
- 조건식의 평가 결과에 따라 반환할 값을 결정한다.
- 조건식 ? 조건식이 true 일때 반환할 값 : 조건식이 false 일때 반환할 값

- 우항과 자항의 피연산자를 논리한다.


8장 제어문
제어문은 조건에 따라 코드 블록을 실행 하거나 반복 실행 시 나타난다.
if...else 문
- 주어진 조건식의 평가 결과에 따라 실행할 코드 블럭을 결정한다.

- if 문과 else문은 2번이상 사용 할 수 없으나, else if 문은 여러 번 사용 가능 하다.
swich 문
- 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮긴다.
반복문
for 문
- 조건식이 거짓으로 평가 될 때까지 코드 블럭을 반복 실행한다.
while 문
- 주어진 조건식의 결과가 참이면 코드 블록을 계속해서 반복 실행한다.
break 문
레이블 문, 반복문 또는 switch 문의 코드 블록을 탈출한다.
- 레이블 문, 반복문 또는 switch 문 외에 사용하면 오류가 난다.
- 레이블 문이란 식별자가 붙는 문
continue 문
반복문의 코드 블록 실행을 현 지점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동시킨다.
break문처럼 반복문을 탈출하지 않는다.
9장 타입 변환
개발자의 의도에 따라 다른 타입으로 변환 하는 것을 명시적 타입 변환, 개발자의 의도와는 상관 없이 다른 타입으로 변환하는 것을 암묵적 타입 변환 이라 한다.
- 명시적 타입 변환, 암묵적 타입 변환 이 기존 원시 값을 직접 변경한는 것은 아니다.
- 원시 값은 변경 불가능한 값이므로 변경할 수 없다.
- 타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다.
암묵적 타입 변환
명시적 타입 변환
- 문자열 타입으로 변환
- 숫자 타입으로 변환
- 불리언 타입
10장 객체 리터럴
자바스크립트는 객체 기반의 프로그래밍 언어이머, 자바스크립트를 구성하는 거의 "모든 것"이 객체이다.
- 객체타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조이다.
- 객체타입의 값은 변경이 가능하다.
- 객체는 0개 이상의 프로퍼티로 구성된 집합이며, 프로퍼티는 키(key) 와 값(value)로 이루어져 있다.
- 객체 리터럴은 중괄호({}) 내에 0개 이상의 프로퍼티를 정의 한다.
프로퍼티
- 객체는 프로퍼티의 집합이며, 키(key) 와 값(value)로 구성된다.
- 프로퍼티를 나열할 때는 쉼표(,)로 구분한다.
- 프로퍼티 키: 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
- 프로퍼티 값: 자바스크립트에서 사용가능한 모든 값
메서드
메서드는 객체에 묶여 있는 함수
- 메서스 내부에서 사용한 this 키워드는 객체 자신을 가리키는 참조변수이다.
프로퍼티 접근
- 마침표 프로퍼티 연산자(.)를 사용하는 마침표 표기법
- 대괄호 프로퍼티 접급 연산자([])를 사용하는 대괄호 표기법
- 대괄호 표기법을 사용하는 경우 대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키가 반드시 따옴표로 감싼 문자열이어야 한다.(따옴표 없을경우 키 값을 식별자로 인식한다!)
프로퍼티 값 갱신
- 이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.
프로퍼티 동적 생성
- 존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당 된다.
프로퍼티 삭제
- delete 연산자는 객체의 프로퍼티를 삭제한다.
let person = {name :'kim'}
person.age = 26;
delete person.age
console.log(person)
결과: { name: 'kim' }
프로퍼티 축약 표현
- ES6에서는 프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략 할 수 있다.
- 문자열 또는 문자열로 변환할 수 있는 값으로 평가되는 표현식을 사용해 프로퍼티 키를 동적으로 생성할 수 있다.
- ES6에서는 객체 리터럴 내부에서도 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성할 수 있다.
- ES6에서는 메서드 정의시 function 키워드 생략 가능
11장 원시 값과 객체의 비교
- 문자열과 불변성
- ECMAScript에서 문자열 타입(2바이트), 숫자 타입(8바이트) 롤 공간의 크기가 정해져있다.
- 문자열은 몇 개의 문자로 이루어졌냐에 따라 메모리 공간의 크기가 정해진다.
- 문자열은 유사 배열 객체이면서 이터러블 이므로 배열과 유사하게 각 문자에 접근 할 수 있다.
- 유사 배열 객체: 배열처럼 인덱스로 프로퍼티 값에 접근 가능하고 length 프로퍼티를 갖는 객체
객체
- 객체는 프로퍼티의 개수가 정해져 있지 않으면, 동적으로 추가및 삭제가 가능하다.
- 객체는 메모리 공간의 크기를 사전에 정해 둘 수 없다.
- 객체 값은 변경 가능한 값이다.
- 객체를 할당한 변수는 재할당 없이 객체를 직접 변경 할 수 있다.
let person = {name :'kim'}
person.age = 26;
console.log(person)
결과 { name: 'kim', age: 26 }
객체 자료형의 얕은 복사, 깊은 복사
얕은 복사는 참조 타입 데이터가 저장한 '메모리 주소 값'을 복사한 것
깊은복사: 새로운 메모리 공간을 확보하여 내부의 객체값까지 완전히 복사하는 것
얕은 복사
- slice()
- spread syntak
- obiect assign()
slice()
let arr = [0, 1, 2, 3];
let copiedArr = arr.slice();
console.log(copiedArr); // [0, 1, 2, 3]
console.log(arr === copiedArr); // false
spread syntak
let arr = [0, 1, 2, 3];
let copiedArr = [...arr];
console.log(copiedArr); // [0, 1, 2, 3]
console.log(arr === copiedArr); // false
copiedArr.push(4);
console.log(copiedArr); // [0, 1, 2, 3, 4]
console.log(arr); // [0, 1, 2, 3]
object assign
let obj = { firstName: "coding", lastName: "kim" };
let copiedObj = Object.assign({}, obj);
console.log(copiedObj) // { firstName: "coding", lastName: "kim" }
console.log(obj === copiedObj) // false
💢참조 자료형이 몇 단계로 중첩되어 있던지, 위에서 설명한 방법으로는 한 단계까지만 복사할 수 있습니다.
let users = [
{
name: "kimcoding",
age: 26,
job: "student"
},
{
name: "parkhacker",
age: 29,
job: "web designer"
},
];
let copiedUsers = users.slice();
→user === copiedUsers를 해보면 false 가 나온다. 그러나 user[0] === copiedUsers[0]을 해보면 true값이 나온다.
깊은 복사
- JSON.stringify()
- JSON.parse()
- lodash
- ramda
💢 JavaScript 내부적으로는 깊은 복사를 수행할 수 있는 방법이 없습니다
JSON.stringify()는 참조 자료형을 문자열 형태로 변환하여 반환하고, JSON.parse()는 문자열의 형태를 객체로 변환하여 반환.
JSON.stringify()와 JSON.parse()
const arr = [1, 2, [3, 4]];
const copiedArr = JSON.parse(JSON.stringify(arr));
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
💢 자료형 중에 함수가 포함되어 있을 경우 위 방법을 사용하면 함수가 null로 바뀌게 됩니다
자료형 중에 함수가 포함되어 있을 경우
const arr = [1, 2, [3, function(){ console.log('hello world')}]];
const copiedArr = JSON.parse(JSON.stringify(arr));
console.log(arr); // [1, 2, [3, function(){ console.log('hello world')}]]
console.log(copiedArr); // [1, 2, [3, null]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
외부 라이브러리 lodash 사용
const lodash = require('lodash');
const arr = [1, 2, [3, 4]];
const copiedArr = lodash.cloneDeep(arr);
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false