자바스크립트 Study/자바스크립트

JS (ES6 & above) - Objects

코르시카 2021. 4. 17. 14:13

■ Object - literal / constructor

> Object 생성은 literal / constructor 방식이 있음

여러 데이터를 변수에 담는 것 보다 container로 Object를 사용하여 좀더 관련있고 효율적으로 관리 가능

- new 키워드 참조 : korshika.tistory.com/67

// 1. Literals and property
function print(person) {
  console.log(person.name);
  console.log(person.age);
}

// Object로 save
// 괄호 방식 : Object literal
const hojune = {name : 'hojune', age: 4};
hojune.hasJob = true; // dynamic하게 property 추가 가능
hojune.isGraduated = true;
delete hojune.isGraduated; // property 삭제 가능 
print(hojune);

// new 방식 : Object constructor
const me = new Object(); // property dynamic하게 추가

 

 

■ Computed properties

JS의 Object는 Python의 class + dict 합쳐진것과 매우 유사한 느낌...

> 다음과 같이 string으로 runtime 동작 동안 string으로 key를 입력하여 받는 것을

   computed properties 사용한다고 함

// 2. Computed properties
console.log(hojune.name);
console.log(hojune['name']); // key를 string으로 검색 가능
hojune['hasJob'] = true; // 마찬가지로 할당 가능
// string으로 검색 = computed properties

> runtime에 . 로 proptery를 pre-coding 할 수 없는 경우가 있기 때문

const hojune = {name : 'hojune', age: 4};

function printValue(obj, key){

  //key는 어떤 object의 property 출력할지
  // 왜냐하면 .dot으로 property만 
  // runtime에 dynamic하게 가져올 수 없기 때문에
  console.log(obj[key]);
}
printValue(hojune, "name");

>>> hojune

 

 

■ Property value - short hand

너무 반복적으로 literal 하게 Object 생성하기 어려울 때 방법

(1) Object 자체를 생성하여 return하는 builder같은 function 사용

(2) 함수 선언식 생성자를 new 키워드를 통해 변수에 할당

....
const person1 = {name:'bob', age:2};
const person2 = {name:'steve', age:3};
.... // 너무 반복작업

const person3 = MakePerson('hojune', 27);
const person4 = new MakePerson_2('newMan', 4);

// successfully returns Object if key, value are the same
function MakePerson(name, age){
  return {
    name,
    age
  }
}

// 함수 선언식 생성자
// ES6에 class 도입되기 전에 사용하던 방식
// Object마냥 쓸 수 있으므로 이렇게 사용, new 키워드로 호출, 시작은 대문자
function MakePerson_2(name, age){
    // new 키워드 때문 
    // this = {} 문맥상 생성
    this.name = name;
    this.age = age;

    // return this;
}

 

 

■ Object property check

(1) computed properties로 dynamic하게 undefined로 나오는지

(2) in 키워드로 확인

(3) hasOwnProperty 매써드 사용

// 5. 'in' Operator  : property existance check
// key in Object
let person5 = new MakePerson_2('person5', 4);
console.log("'name' in person5 : ", 'name' in person5);
console.log("Object.prototype.hasOwnProperty : ", person5.hasOwnProperty('name'));

>>>
'name' in person5 :  true
Object.prototype.hasOwnProperty :  true

 

 

■ For... in   /   For... of

※ array 에서는 for(index, condition, step) 이 더 convention에 맞는 형태

※ 강의에서는 for...of는 쓴다고 하심

 

여기서는 Object 안의 key를 iteration 하는 것을 의미

// for(key in obj)
console.clear();
for(key in person5){
  console.log(key);
}

>>>
name
age

// for(value of iterable)
const array = [1,2,4,5];
for(let i=0; i < array.length; i++){
  console.log('simple access to array index : ',array[i]);
}

>>>
simple access to array index :  1
simple access to array index :  2
simple access to array index :  4
simple access to array index :  5


for(val of array){
  console.log('val by for..of : ', val);
}
>>>
val by for..of :  1
val by for..of :  2
val by for..of :  4
val by for..of :  5

 

 

■ Object cloning

> Object는 항상 reference로 전달, 할당도 마찬가지

const user = {name : 'hojune', age:20};
const user2 = user;
user2.name = 'coder';
console.log(user);

>>> 
// reference가 같기 때문
// user2를 변경해도 ref가 같이 변경되어서 user도 변화
{ name: 'coder', age: 20 }

user, user2가 같은ref를 가르키고 있음

(1) Shallow copy 방식

※ deep 한 객체를 가지는 프로퍼티가 있는 경우 그대로 ref를 같이 가져감

> key를 하나씩 복사 / Spread operator(array shallow 복사가능) / Object.assign

// key copy
// shallow copy (객체 내부의 객체는 복사 안됨)
const user3 = {};
for(key in user){
  user3[key] = user[key]; // copy but assigning
}

>>>
{ name: 'coder', age: 20 }

// spread operator
// shallow copy (객체 내부의 객체는 복사 안됨)
const user3_new = { ...user3 };


//better way
// Object의 매써드를 호출해서 사용
// shallow copy (객체 내부의 객체는 복사 안됨)
const user4 = Object.assign({}, user3);
console.log('check user4 : ', user4);
user4.name = 'hidden';
console.log('user3 : ', user3);
console.log('user4 : ', user4);

>>>
check user4 :  { name: 'coder', age: 20 }
user3 :  { name: 'coder', age: 20 }
user4 :  { name: 'hidden', age: 20 }

 

(2) deep copy

추가 참조 : junwoo45.github.io/2019-09-23-deep_clone/

> JSON 사용

(python pickle마냥, string 하면서 function이 undefined되는 등의 문제)

느리지만, 그외deep copy는 적용 됨

const cloneObj = obj => JSON.parse(JSON.stringify(obj));

const original = {
  a: 1,
  b: {
    c: 2,
  },
  d: () => {
    console.log("hi");
  },
};

const copied = cloneObj(original);
console.log('original : ', original);
console.log('final output of copied : ', copied); // undefined

>>>
original :  { a: 1, b: { c: 2 }, d: [Function: d] }
final output of copied :  { a: 1, b: { c: 2 } }

> Lodash deepclone

const clonedeep = require("lodash.clonedeep")

const original = {
  a: 1,
  b: {
    c: 2,
  },
  d: () => {
    console.log("hi")
  },
}

const deepCopied = clonedeep(original)

original.a = 1000
original.b.c = 2000

console.log(deepCopied.a) // 1
console.log(deepCopied.b.c) // 2
console.log(deepCopied.d()) // 'hi'

참조 :

youtube.com/watch?v=1Lbr29tzAA8&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=7

 

반응형