rustandbone Developer

모던 JS deep dive 2회차 챕터 9~11

모던 JS deep dive 2회차

09. 타입 변환과 단축 평가

9.1 타입 변환이란?

명시적 타입 변환(explicit coercion) 또는 타입 캐스팅(type casting) : 개발자의 의도에 따라 다른 타입으로 변환하는 것
=> 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 드러남

암묵적 타입 변환(implicit coercion) 또는 타입 강제 변환(type coercion) : 개발자의 의도와 상관없이 표현식 평가하는 도중에 암묵적으로 타입이 장동 변환되는 것
=> 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 나타나지 않음

중요한 것은 코드를 예측할 수 있어야 한다는 것. 동료가 작성한 코드를 정확히 이해할 수 있어야 하고, 자신이 작성한 코드도 동료가 쉽게 이해할 수 있어야 함

9.2.3 불리언 타입으로 변환

자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy 값(참으로 평가되는 값) 또는 Falsyt 값(거짓으로 평가되는 값)으로 구분한다.

9.4.2 옵셔널 체이닝 연산자

ES11(ECMAScript2020)에서 도입된 옵셔널 체이닝 연산자 ?.는 좌항의 피연산자가 null 또는 undefined인 경우, undefined를 반환, 그렇지 않으면 우항의 프로퍼티 참조 이어감

?.는 좌항 피연산자가 false로 평가되는 Falsy 값(false, 0, -1, NaN, ‘‘)이라도 null 또는 undefined가 아니면 우항의 프로퍼티 참조 이어감

9.4.3 null 병합 연산자

ES11(ECMAScript2020)에서 도입된 null 병합(nullish coalescing) 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자 반환, 그렇지 않으면 좌항의 피연산자 반환

??는 변수에 기본값 설정할 때 유용. 좌항의 피연산자가 false로 평가되는 Falsy 값(false, 0, -1, NaN, ‘‘)이라도 null 또는 undefined가 아니면 좌항의 피연산자를 그대로 반환

10. 객체

10.1 객체란?

자바스크립트는 객체 기반의 프로그래밍 언어. 자바스크립트를 구성하는 거의 ‘모든 것’이 객체. 원시 값을 제외한 나머지 값(함수, 배열, 정규 표현식 등)은 모두 객체.

객체 타입은 다양한 타입의 값(원시 값 또는 다른 객체)을 하나의 단위로 구성한 복합적인 자료구조다.

원시 타입의 값, 즉 원시 값은 변경 불가능한 값(immutable value)이지만
객체 타입의 값, 즉 객체는 변경 가능한 값(mutable value)

객체는 0개 이상의 프로퍼티로 구성된 집합, 프로퍼티는 키와 값으로 구성됨

자바스크립트에서 사용 가능한 모든 값은 프로퍼티 값이 될 수 있음.
함수도 프로퍼티 값으로 사용 가능. 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메서드(method)라고 부름.

  • 프로퍼티 : 객체의 상태를 나타내는 값(data)
  • 메서드 : 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)

객체는 객체의 상태를 나타내는 값(프로퍼티)과 프로퍼티를 참조하고 조작할 수 있는 동작(메서드)을 모두 포함할 수 있기 때문에 상태동작을 하나의 단위로 구조화할 수 있어 유용함

10.2 객체 리터럴에 의한 객체 생성

객체 리터럴의 중괄호는 코드 블록을 의미하지 않음. 객체 리터럴은 값으로 평가되는 표현식. 따라서 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론을 붙임.

객체 리터럴은 자바스크립트의 유연함과 강력함을 대표하는 객체 생성 방식. 클래스를 정의하고 new 연산자와 함께 생성자를 호출할 필요 없음

10.3 프로퍼티

객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성됨

  • 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값
firstName; //식별자 네이밍 규칙을 준수하는 프로퍼티 키
("last-name"); //식별자 네이밍 규칙을 준수하지 않는 프로퍼티 키

문자열 또는 문자열로 평가할 수 있는 표현식을 사용해 프로퍼티 키를 동적 생성 가능. 표현식을 대괄호[]로 묶어야 함

var obj = {};
var key = 'hello';
obj[key] = 'world;

console.log(obj) // {hello: "world"}

10.4 메서드

프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라고 부름

10.5 프로퍼티 접근

  • 프로퍼티 접근 방법
    • 마침표 프로퍼티 접근 연산자를 사용하는 마침표 표기법(dot notation)
    • 대괄호 프로퍼티 접근 연산자를 사용하는 대괄호 표기법(bracket notation)

대괄호 표기법을 사용하는 경우
대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 함. 감싸지 않으면 자바스크립트 엔진은 식별자로 해석함

11. 원시 값과 객체의 비교

  • 7가지 데이터 타입
    • 숫자
    • 문자열
    • 불리언
    • null
    • undefined
    • 심벌
    • 객체 타입
  • 원시 타입 / 객체 타입으로 구분

원시 타입의 값, 즉 원시 값은 변경 불가능한 값(immutable value)
객체(참조) 타입의 값, 즉 객체는 변경 가능한 값(mutable value)

원시 값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장
객체를 변수에 할당하면 변수(확보된 메모리 공간)에는 참조 값이 저장

원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달
=> 값에 의한 전달(pass by value)
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달
=> 참조에 의한 전달(pass by reference)

11.1 원시 값

11.1.1 변경 불가능한 값

원시 타입의 값, 즉 원시 값은 변경 불가능한 값임. 한 번 생성된 원시 값은 읽기 전용(readonly) 값으로서 변경할 수 없음.

변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간 확보하고, 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간주소 변경 => 불변성(immnutability)

불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없음

11.1.2 문자열과 불변성

  • ECMAScript 사양
    • 문자열 타입 - 2바이트
    • 문자열은 0개 이상의 문자(character)로 이뤄진 집합, 1개의 문자는 2바이트의 메모리 공간에 저장됨
    • 숫자 타입 - 8바이트
    • 숫자값은 1도, 10000도 동일한 8바이트 필요.
    • => 이외 원시 타입은 크기를 명확히 규정하고 있지 않음

문자열은 유사 배열 객체이면서 이터러블. 배열과 유사하게 각 문자에 접근 가능

유사 배열 객체 : 마치 배열처럼 인덱스로 프로퍼티 값에 접근 가능하고, length 프로퍼티를 갖는 객체. 원시 값을 객체처럼 사용하면 원시 값을 감싸는 래퍼 객체로 자동 변환

var str = "string";

str[0] = "S";
//배열과 유사하게 인덱스를 사용해 각 문자에 접근 가능
//이미 생성된 문자열의 일부 문자를 변경해도 반영되지 않음.
//에러는 발생하지 않음

원시 값은 어떤 일이 있어도 불변. 데이터의 신뢰성 보장.

11.1.3 값에 의한 전달

변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달 됨
=> 값에 의한 전달

var score = 80;
var copy = score;
console.log(score === copy); //true

둘 다 숫자 80을 갖지만, 다른 메모리 공간에 저장된 별개의 값임

값에 의한 전달 : 엄격하게 표현하면 값이 전달되는 것이 아니라 메모리 주소가 전달. 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억

식별자로 값을 구별해서 식별한다는 것은 식별자가 기억하고 있는 메모리 주소를 통해 메모리 공간에 저장된 값에 접근할 수 있다는 것을 의미. 식별자는 메모리 주소에 붙인 이름이라고 할 수 있음

‘값에 의한 전달’도 사실은 값을 전달하는 것이 아니라 메모리 주소 전달. 단, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있음

결국은 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없는 것

11.2 객체

11.2.1 변경 가능한 값

객체(참조) 타입의 값, 즉 객체는 변경 가능한 값(mutable value).

객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값(reference value)에 접근 가능. 참조 값은 생성된 객체가 저장된 메모리 공간의 주소, 그 자체임

객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근

객체는 변경 가능한 값. 따라서 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있음. 재할당 없이 프로퍼티를 동적 추가하거나 프로퍼티 값 갱신하거나 프로퍼티 자체를 삭제할 수 있음

객체는 변경 가능한 값이므로 메모리에 저장된 객체를 직접 수정할 수 있음

객체를 생성하고 관리하는 방식은 매우 복잡하고 비용이 많이 드는 일.
원시 값처럼 복사해서 새롭게 생성한다면 메모리의 효율적 소비가 어렵고 성능이 나빠짐

메모리를 효율적으로 사용하기 위해, 그리고 객체를 복사해 생성하는 비용을 절약하여 성능을 향상시키기 위해 객체는 변경 가능한 값으로 설계됨.

구조적 단점 : 여러 개의 식별자가 하나의 객체를 공유할 수 있음

값에 의한 전달
참조에 의한 전달
=> 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일
식별자가 기억하는 메모리 공간, 즉 변수에 저장되어 있는 값이 원시 값이냐 참조 값이냐 차이만 있을 뿐

자바스크립에는 ‘참조에 의한 전달’은 존재하지 않고 ‘값에 의한 전달’만이 존재한다고 할 수 있음

값 종류를 원시 값인지 참조 값인지 구별해서 강조하는 의미에서 ‘값에 의한 전달’과 ‘참조에 의한 전달’로 구분하여 부르기로 함