ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JS-객체
    프로그래밍/Js 2021. 5. 12. 13:58

    0. 객체

    - 객체는 몇 가지 특수한 기능을 가진 연관배열이다
    - 객체는 프로퍼티(키-값)을 저장한다
    - 프로퍼티 키는 문자열이나 심볼이어야 한다. 보통은 문자열이다
    - 값은 어떤 자료형도 가능하다


    1. 계산된 프로퍼티

    - 객체를 만들 때 객체 리터럴 안의 프로퍼티 키가 대괄호로 둘러 싸여 있는 경우, 이를 계산된 프로퍼티라고 부른다.

    let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple"); 
    let bag = { [fruit]: 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아 온다 
    alert( bag.apple ); // fruit에 "apple"이 할당되었다면, 5가 출력된다.

    2.'in' 연산자로 프로퍼티 존재 여부 확인하기

    - 연산자 in을 사용하면 프로퍼티 존재여부를 확인할 수 있다

    let user = { name: "John", age: 30 };
    alert( "age" in user ); // user.age가 존재하므로 true가 출력된다
    alert( "blabla" in user ); // user.blabla는 존재하지 않기 때문에 false가 출력된다.

    3. 객체 정렬방식

    - 정수 프로퍼티는 자동으로 정렬. //정수프로퍼티: 변형없이 정수에서 왔다갔다 할 수 있는 문자열

    - 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬.

    let codes = {
      "49": "독일",
      "41": "스위스",
      "44": "영국",
      // ..,
      "1": "미국"
    };
    
    for (let code in codes) {
      alert(code); // 1, 41, 44, 49
    }

    4. 참조에 의한 객체 복사

    - 객체와 원시타입의 근본적인 차이 중 하나는 객체는 '참조에 의해 ' 저장되고 복사 된다.

    - 즉 변수엔 객체에대한 '참조 값'이 저장 된다

    - 새로운 객체를 만들어주는 Object.assign이라는 내장 함수가 있다.

    let user = {
      name: "John",
      age: 30
    };
    
    let clone = Object.assign({}, user);
    
    user === clone // false

    5. 가비지 컬렉션

    - 자바스크립트는 '도달 가능성'이라는 개념을 사용해 메모리 관리를 수행한다.
    - 루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이다

    1. let user = {
      name: "John"
    };
    
    2. user = null;
    
    //이제 John은  도달할 수 없는 상태. 따라서 가비지 컬렉션은 John을 메모리에서 삭제.

    6.메서드와 this

    - this 값은 런타임시에 결정된다. 컨텍스트에 따라 달라진다.
    - 즉 동일한 함수라도 다른 객체에서 호출했다면 'this'가 참조하는 값이 달라진다.

    let user = { name: "John" };
    let admin = { name: "Admin" };
    
    function sayHi() {
      alert( this.name );
    }
    
    // 별개의 객체에서 동일한 함수를 사용함
    user.f = sayHi;
    admin.f = sayHi;
    
    // 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
    // this 값이 달라짐
    user.f(); // John  (this == user)
    admin.f(); // Admin  (this == admin)

    - this가 런타임 시 결정되면 좋은 점은 함수를 하나만 만들어 여러 객체에서 재사용할 수 있는 점.
    - but, 이런 유연함이 실수로 이어질 수 있다.

    7. 'new' 연산자와 생성자 함수

    - "new" 연산자와 생성자 함수를 사용하면 유사한 객체 여러개를 쉽게 만들 수 있다.
    - 생성자 함수
    1. 함수이름의 첫글자는 대문자
    2. "new" 연산자를 붙여 실행

    function User(name) {
      this.name = name;
      this.isAdmin = false;
    }
    
    let user = new User("Jack");
    
    alert(user.name); // Jack
    alert(user.isAdmin); // false

    - new User(...)를 써서 함수를 실행하면 아래와 같이 작동합니다
    1. 빈 객체를 만들어 this에 할당
    2. 함수 본문을 실행.
    3. this를 반환
    - 재사용할 필요가 없는 복잡한 객체를 만들때는 new function(){...}을 사용하자

    let user = new function() {
      this.name = "John";
      this.isAdmin = false;
    }
    //위 생성자는 어디에도 저장하지 않음.

    - 생성자 함수엔 보통 return 문이 없는데, 반환해야 할 것들은 모두 this에 저장 되고, this는 자동반환 되기때문이다.
    - 만약 return 문이 있다면?
    1. 객체를 return 한다면, this 대신 객체가 반환
    2. 원시형을 return 한다면, return 문 무시

    function BigUser() {
      this.name = "John";
      return { name: "Godzilla" };  // <-- this가 아닌 새로운 객체를 반환함
    }
    
    alert( new BigUser().name );  // Godzilla

    8. 옵셔널 체이닝 '?.'

    - 옵셔널 체이닝 ?.을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 사용 가능
    - 옵셔널 체이닝이 등장하기 전에는 값이 존재하는 지 확인 하기 위해 &&연산자를 사용하곤 하였는데, 코드가 길어지는 단점이 있었다.
    - ?.은 '앞'의 평가 대상이 undefined나 null 일 경우 멈추고 undefined를 반환한다.

    let user = null;
    let x = 0;
    
    user?.sayHi(x++); // 아무 일도 일어나지 않는다
    
    alert(x); // 0, x는 증가하지 않음.
    let user1 = {
      admin() {
        alert("관리자 계정입니다.");
      }
    }
    
    let user2 = {};
    
    user1.admin?.(); // "관리자 계정입니다." 출력
    user2.admin?.();
    let user1 = {
      firstName: "Violet"
    };
    
    let user2 = null; // user2는 권한이 없는 사용자라고 가정해보자
    
    let key = "firstName";
    
    alert( user1?.[key] ); // Violet
    alert( user2?.[key] ); // undefined

    - delete와도 조합해 사용할 수 있다. (이전에는 무조건 먼저 if문을 쓰고 delete문을 사용했었는데...)

    let user1 = {
      firstName: "Violet"
    };
    
    let user2 = null; // user2는 권한이 없는 사용자라고 가정해보자
    
    let key = "firstName";
    
    alert( user1?.[key] ); // Violet
    alert( user2?.[key] ); // undefined

    - but, ?.은 읽기, 삭제하기에는 사용 가능 하지만 쓰기에는 사용할 수 없다.

    user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment
    // 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문이다.

    9.심볼형

    - 자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용한다.
    - 심볼은 유일한 식별자를 만들고 싶을 때 사용한다.
    - 심볼을 만들 때 심볼 이름이라 불리는 설명을 붙일 수도 있다.
    - 심볼은 유일성이 보장되기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼 값은 다르다.

    // 심볼 id에는 "id"라는 설명이 붙인다.
    let id1 = Symbol("id");
    let id2 = Symbol("id");
    
    alert(id1 == id2); // false

    - 심볼은 문자형으로 자동형변환 되지 않기 때문에, 만약 반드시 출력을 해주어야 하는 사항이라면 다음과 같이 toString, description메서드를 사용한다.

    let id = Symbol("id");
    alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨
    
    let id = Symbol("id");
    alert(id.description); // "id"  설명이 출력 

    - 심볼을 이용해서 '숨김 프로퍼티 '를 만들 수 있다.
    - 만약, 서드 파티 코드에서 가지고 온 user라는 객체가 여러개 있고, user를 이용해 어떠한 작업을 해야하는 상황이라서 user 에 식별자를 붙여줘야한다면...

    let user = { // 서드파티 코드에서 가져온 객체
      name: "John"
    };
    
    let id = Symbol("id");
    
    user[id] = 1;
    
    alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있습니다

    - 문자열 "id"대신 Symbol('id")사용한 이유는?심볼은 유일성이 보장되기때문에, 만약 또 다른 user객체가 있더라도 식별자끼리 충돌 안함.
    - 심볼을 사용하면 서드파티 코드가 모르게 user에 식별자를 부여할 수 있음.
    - 객체 {...}를 만든 경우 , 대괄호를 사용해 심볼형 키를 만들어야 한다.

    let id = Symbol("id");
    
    let user = {
      name: "John",
      [id]: 123 // "id": 123은 안됨
    };

    - 심볼은 for...in 반복문, Object.key에서 배제 된다. but, Object.assign()에서는 배제하지않고 복사된다.
    - 전역 심볼을 만들기 위해서는 Symbol.for(key)를 사용한다

    let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만든다.
    // 동일한 이름을 이용해 심볼을 다시 다시 읽는다.
    let idAgain = Symbol.for("id");
    // 두 심볼은 같습니다.
    alert( id === idAgain ); // true

    - Symbol.keyFor()를 사용하면 전역 심볼 이름을 알 수 잇다

    let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만든다.
    // 동일한 이름을 이용해 심볼을 다시 다시 읽는다.
    let idAgain = Symbol.for("id");
    // 두 심볼은 같습니다.
    alert( id === idAgain ); // true

     

    *참조 : ko.javascript.info/

    '프로그래밍 > Js' 카테고리의 다른 글

    new Function 문법  (0) 2021.07.05
    객체로서의 함수와 기명 함수 표현식  (0) 2021.07.02
    JS - 추상관계비교  (0) 2021.02.24
    JS-parseInt 문자열→숫자로 파싱  (0) 2021.02.22
    JS - Boolean 타입 강제변환  (0) 2021.02.18
Designed by Tistory.