ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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) 대괄호 연산자: 대괄호 안에는 프로퍼티 이름인 문자열이나 심볼로 평가 되는 표현식. 즉, 변수도 가능하다.

    대괄호 연산자의 실제 사례

    서버에서 오는 데이터가 배열의 key값의 규칙과 대괄호 연산자의 특성을 이용해 위와 같은 코드를 작성했다.

     

    프로퍼티 접근 에러: 중요!!!!

    객체 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 vs for of 반복문 정리

    ES6 공부하면서 for in 과 for of 차이점이 뭔지 궁금해서 찾아보다가 정리해보았습니다. 잘못된 부분이 있으면 커멘트 부탁드려요~ http://itstory.tk/entry/Javascript-for-in-vs-for-of-반복문 foreach 반복문 foreac

    jsdev.kr

     

    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)

    이런 코드를 리액트에서도 간간히 봤을 것. 아래 코드가 그 예시다.

    출처: https://react.vlpt.us/basic/09-multiple-inputs.html

     

    3) 심벌은 프로퍼티 이름으로 쓸 수 있음.

    심벌이 반환하는 값은 다른 심벌값이나 다른 문자열과 같지 않으므로, 프로퍼티 이름이 겹치지 않는다.

    심지어 같은 문자를 인자로 심벌을 생성해도 서로 다른 값을 반환한다.

     

    심벌은 나도 공부중. 아래 사이트가 정리가 잘 되어 있으니 보고 공부하자.

    https://poiemaweb.com/es6-symbol

     

    Symbol | PoiemaWeb

    Symbol은 ES6에서 새롭게 추가된 7번째 타입이다. Symbol은 애플리케이션 전체에서 유일하며 변경 불가능한(immutable) 원시 타입의 값이다. 주로 객체의 프로퍼티 키(property key)로 사용한다.

    poiemaweb.com

     

    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 쓰는 예 보여주기.

     

     

     

    댓글

금손이 프론트엔드 개발자가 되고자 오늘도 존버중