JS (ES6 & above) - Objects
■ 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 }
(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