-
6장 객체: 코뿔소 자바스크립트 완벽 가이드 스터디 모임항해99 1기 수료후 TIL 2022. 6. 8. 02:45
객체: 자바스크립트의 가장 기본적인 데이터 타입.
오늘의 목표: 객체의 동작 원리를 자세하게 이해하자.
6-1. 객체 소개
객체란?
1) 복합된 값
2) 프로퍼티의 순서 없는 집합
3) 이름(key)을 통해서 값(value)을 저장하고 불러온다.
4)이름과 값을 연결하는 데이터 타입은 다른 언어에도 있음. 파이썬에서는 딕셔너리.
5) 자신의 프로토타입이 있으면 그것에서 프로퍼티를 상속 받음: 자바스크립트의 중요한 기능!
6) 객체의 메서드(ex: toLocaleString)은 일반적으로 상속된 프로퍼티.
7) JS에서는 문자열, 숫자, 심벌, boolean, null, undefined가 아니면 모두 객체. 그래서 배열도 객체.
8) 객체는 가변(= 동적)
9) 값이 아니라 참조로 동작함. 그래서 같은 객체를 할당한 변수들 중의 하나를 조작하면 다른 변수들도 같이 변함.
10) 프로퍼티 이름(key)는 문자열(빈 문자열 포함), 심벌 가능. 같은 key는 존재 불가.
11) 프로퍼티 값(value)는 모든 타입이 가능. getter, setter도 가능.
12) 상속 되지 않은 프로퍼티 = 자체 프로퍼티
13) 프로퍼티의 세가지 속성: 쓰기 가능, 열거 가능, 변경 가능.
6-2. 객체 생성
세가지 생성법이 있다.
1) 객체 리터럴
2) new 연산자: new 뒤에 반드시 생성자 함수 호출
3) Object.create()
첫번째 인자를 프로토타입 삼아서 새 객체를 생성하는 방법.
let o1 = Object.create({x: 1, y: 2}); // o1 = { x: 1, y: 2} console.log(o1.x + o1.y) // 1 + 2 = 3
인자가 null일 경우 프로토타입이 없는 객체가 생성 된다.
그래서 아무것도 상속 받지 않는 객체가 된다.
let o2 = Object.create(null) console.log(o2) // o2 = {}
객체 리터럴이나 new Object()로 만든 객체처럼, 일반적인 빈 객체(프로토타입 상속 받는 객체)를 만들고 싶다면 다음과 같이 하면 된다.
let o3 = Object.create(Object.prototype)
Object,create()를 사용하는 이유 중 하나: 3rd-party library에서 객체 변경 하는 사고 막기
let obj = { x: "don't change this value" } // library.function(o) // 라이브러리 함수에 의해 객체에 의도치 않은 변경이 있을 수 있음 library.function(Object.create(o)) // 의도치 않은 변경을 막는다
6-3. 프로퍼티 검색과 설정.
자바스크립트의 객체는 문자열을 인덱스로 사용한다.(그러므로, JS 객체 === 연관 배열)
프로퍼티 값(value)에 접근하기 위해서 key를 인자로 받는 연산자: 점(.) or 대괄호([]) 사용
1) 점 연산자: 점 오른쪽의 key는 반드시 프로퍼티의 이름인 단순 식별자
2) 대괄호 연산자: 대괄호 안에는 프로퍼티 이름인 문자열이나 심볼로 평가 되는 표현식. 즉, 변수도 가능하다.
대괄호 연산자의 실제 사례
프로퍼티 접근 에러: 중요!!!!
객체 o가 존재하는데, o에 없는 프로퍼티를 검색하는 경우 = 에러 아님. 그냥 undefined로 처리 됨.
객체 o가 존재하지 않는데(= 객체가 null 또는 undefined), 그 객체의 프로퍼티를 읽기 시도 = 에러 발생
접근 에러가 발생할 수 있는 코드와 에러를 원천 차단한 코드 예
1) send 객체가 null 또는 undefined라면 에러 발생이 가능한 코드
2) 에러가 발생하지 않도록 처리한 코드
3) 또 다른 예시 코드: 중간의 if 문이 객체가 null 또는 undefined일 경우 오류가 생기지 않게 예외처리 했다.
또는 ES2020에서 지원하는 optional chaining 9조건부 프로퍼티 접근 연산자) ?. 를 활용하기
6-4. 프로퍼티 삭제
delete 연산자는 객체 프로퍼티 삭제. 값(value)만 없애는 게 아니라 해당 프로퍼티를 통째로 삭제.
delete 연산자 특성: 삭제 성공 or 없는 프로퍼티 삭제 시도 해도 true로 평가 됨.
6-5. 프로퍼티 테스트
JS는 객체는 프로퍼티 집합: 특정 key를 갖는 프로퍼티 존재 확인 필요하기도 함.
1) in 연산자
2) hasOwnProperty() 메서드
3) propertyIsEnumerable() 메서드
4) !==undefined
5) in 연산자는 존재하지 않는 프로퍼티, 존재하는데 값(value)가 undefined인 프로퍼티 구분 가능.
6-6. 프로퍼티 열거
객체의 열거는 for / in 루프를 사용한다. (배열의 열거는 for / of 루프 사용)
* for / in 루프와 for / of 루프 차이 참고 블로그
https://jsdev.kr/t/for-in-vs-for-of/2938
for / in 루프보다,객체 프로퍼티 이름(=key)을 배열에 저장해서 for / of 루프로 사용하는 편이 더 쉽다.
프로퍼티 이름을 배열로 저장할 수 있는 함수 4가지.
Object.key(), Object.getOwnPropertyNames(), Object.getOwnPropertySymbols(), Reflect.ownKeys()
6-7. 객체 확장
객체 확장: 한 객체의 프로퍼티를 다른 객체에다 복사하기
객체 복사의 목적: 소스 객체에 기본값을 정의해두고 대상 객체에다 그 값들을 복사해서 쓰기
객체 확장 메서드: Object.assign()
Object.assign() 제대로 쓰기
1) 옳지 못한 예
아래와 같이 하면 객체 obj1가 값을 유지하지 못하고 변경 된다.
2) 제대로 쓴 예
아래와 같이 해야 객체 새로 생성된 객체 objCopy가 의도에 맞게 생성된다.
3) spread 연산자 사용
이렇게 하면 2)에서 했던 것과 같은 결과를 얻는다.
6-8. 객체 직렬화
객체 직렬화 = 객체를 문자열로 변환 하는 작업.
JSON.stringify():
객체를 직렬화 하는 함수.
열거 가능한 '자체' 프로퍼티만 직렬화.
열거 불가능한 함수는 직렬화 안됨.
symbol도 열거 안 되므로 직렬화 불가.
함수와 symbol이 열거 불가능한 건 책 165-16쪽 참고.
참고 유튜브 영상은 '드림코딩엘리'의 JSON 편에서 12분 30초 ~ 13분 0초 부근 참고https://www.youtube.com/watch?v=FN_D4Ihs3LE
JSON.parse(): 직렬화 된 객체를 객체로 되돌리는 함수.
위 함수로 직렬화/ 되돌리기 되는 데이터 타입: 객체, 배열, 문자열, 유한 숫자, boolean, null
NaN, Infinity, -Infinity: null로 직렬화 됨.
Date객체: 직렬화는 되지만 되돌리기는 불가.
6-10. 확장된 객체 리터럴 문법
1) 단축 프로퍼티
key === value 이면 이름 {..., x: x, ...} 가 아니라 { ..., x, ...} 이렇게 간단하게 쓸 수 있다.
2) 계산된 프로퍼티 (computed property)
이런 코드를 리액트에서도 간간히 봤을 것. 아래 코드가 그 예시다.
3) 심벌은 프로퍼티 이름으로 쓸 수 있음.
심벌이 반환하는 값은 다른 심벌값이나 다른 문자열과 같지 않으므로, 프로퍼티 이름이 겹치지 않는다.
심지어 같은 문자를 인자로 심벌을 생성해도 서로 다른 값을 반환한다.
심벌은 나도 공부중. 아래 사이트가 정리가 잘 되어 있으니 보고 공부하자.
https://poiemaweb.com/es6-symbol
4) spread operator
두 객체에 같은 프로퍼티가 있다면 나중 값이 먼저 값을 덮어 쓴다.
spread operator는 자체 프로퍼티만 분해. 상속 받은 프로퍼티는 분해 불가.
5) 단축 메서드
기존 메서드 코드: function을 명시함.
let square = { area: function() {return this.side * this.side} side: 10, } square.area() // 100
단축 메서드: function 명시 불필요
let square = { area() {return this.side * this.side} side: 10, } square.area() // 100
* vue 코드에서 이런 걸 많이 볼 수 있음.
왜냐면 vue에서 쓰는 함수들은 vue instance(객체)안의 메서드로서 정의 되기 때문.
내 vue 코드를 스터디원들에게 보여주기
6) 프로퍼티 getter, setter.
getter, setter: 접근자 프로퍼티의 접근자 메서드.
프로퍼티에 게터, 세터 모두 있음 = 프로퍼티는 읽기, 쓰기 모두 가능
프로퍼티에 게터만 있음 = 프로퍼티는 읽기 전용.
프로퍼티에 세터만 있음 = 프로퍼티는 쓰기(=변경) 전용.
*내 vue 코드에서 getter, setter 쓰는 예 보여주기.
'항해99 1기 수료후 TIL' 카테고리의 다른 글
웹호스팅: 호스팅이라는 서비스의 개념으로 설명하기. (0) 2022.04.24 HTTP 완벽 가이드 3장: HTTP 메시지 (0) 2022.02.10 TIL 2021.7.26 : 자바스크립트 클래스의 this와 파이썬 클래스의 self 비교(feat. React) (1) 2021.07.26 TIL 2021.7.23 : 자바스크립트 호이스팅의 애매함 타파하기 (0) 2021.07.23 TIL 2021.7.21 : 자바스크립트 데이터의 불변성 유지(feat. 가변성) (0) 2021.07.21