본문 바로가기

JS

JS #7-자바스크립트 기초 개념7 (객체)

복습

화살표함수 : 일반 함수를 만들 때 사용한다. 

클래스 : 생성자를 만들 때 사용한다. (객체 중심)

 

<this 관련>

normal function, concise method => 나를 호출한 대상으로 this를 가르킨다. 

Arrow function => this를 바인딩하지 않기 때문에 내 상위 환경에서 this를 가져오도록 설계되어있다. 

 

 

제곱수를 만드는 함수

<화살표함수> 

  let pow = (numeric, powerCount) => {
    let total = 1;
    for (let i = 0; i < powerCount; i++) {
      total *= numeric;
    }
    return total;
  }

 

 

<reduce 메서드 이용>

배열은 Array함수를 사용해서 매개변수만큼의 배열 크기를 갖는 배열을 만든다. 

fill(null)을 통해 그 배열의 방을 모두 null로 채우고, reduce 메서드를 써서 계속해서 누적되는 acc에 numeric을 돌린다. 

=> 배열의 크기만큼 돌아가니까 제곱의 기능이 제대로 작동된다.

 

 

함수와 변수의 연산

변수 x와 함수 a 를 연산하는 경우, 무조건 함수가 먼저 실행된다.

함수는 실행을하면 

 

 

재귀 함수

안쪽 pow가 계산될 때 함수 실행 환경이 설정되고 바깥 pow는 일시 정지 된다. 

다음 조건값을 구할 때에는 또 일시정지가 되고, 새롭게 함수 실행 환경이 실행되는 것이다. 

=> 환경을 쌓아놓는 구간(일시정지) : call stack

 

call stack : last-in-first-out  (후입선출) 

후입선출의 구조를 가지는 것을 'stack' 이라고 한다. 

 

 

 

 

 


 

객체

  • 몇가지 특이한 특성을 가진 유사 배열
  • key, value 값의 쌍으로 이루어져있다. 

 

객체 생성

 

 

점 표기법 : 객체의 프로퍼티를 읽는다. 

 

 

대괄호 접근법

user의 프로퍼티에 접근할 때 변수로써 접근하려면 대괄호를 써야한다. 

key = "name";

user[key]   (O)

ㄴ 이 말인 즉, user의 name 프로퍼티를 가르킨다. 

 

user.key    (X)

ㄴ 이 말은 즉, user의 key라는 명명의 프로퍼티를 가르키므로 오류가 있다.

우리가 원하는 것은 user의 name이기 때문이다. 

 

 

 

단축 프로퍼티 (많이 사용한다)

객체의 값을 변수로 받아오는 경우가 많은데, 이가 key값과 동일한 경우 '단축 프로퍼티' 를 사용한다. 

 

 

 

 

in 연산자로 프로퍼티 확인하기 

부모의 조상까지 검색하므로, 정확하게 체크하기 위해서는 
Object.prototype.hasOwnProperty.call 을 이용해서 객.체.에,만 값이 있는지 정확하게 확인해야한다. 

 

 

객체는 순서 상관이 없다. 
ㄴ 순서가 중요한 경우 배열을 사용하는 것이 효율적이다. 

 

 

CSS 객체 만들기

max-width 와 같이 js 가 인식하지 못하는 경우, ["max-width"] 로 표기한다. 

 

점 표기법으로 객체에 접근하기 
let authUser = {
    uuid: crypto.randomUUID(),
    name: 'tiger',
    email: 'chaeyoungg77@gmail.com',
    isSignIn: false,
    permission: 'paid'
};

// 점(.) 표기법
// authUser 객체의 프로퍼티에 접근해 Console에 출력해봅니다.

console.log(authUser.uuid);
console.log(authUser.name);
console.log(authUser.email);
console.log(authUser.isSignIn);
console.log(authUser.permission = 'free');

 

대괄호 표기법
// 대괄호([]) 표기법
// 유료 사용자 권한(paid User Rights) 이름으로 프로퍼티를 재정의하고
// 대괄호 표기법을 사용해 접근 Console에 출력해봅니다.
console.log(authUser['uuid']);
console.log(authUser['name']);
console.log(authUser['email']);
console.log(authUser['isSignIn']);
console.log(authUser['permission']);

 

 

 

in으로 객체의 키값 여부 확인하기

//해당하는 객체에 키값의 여부를 확인하는 방법 => in
for(let key in authUser){
    console.log(key);
}

 

 

object.keys()
객체의 키들만 모아놓는 배열 

object.values()
객체의 값들만 모아놓은 배열

 

 

object.entries()
객체의 키와 값을 쌍으로 모으놓은 배열

 

 

제거 VS 삭제

제거 : 값에 null 값을 주는 것
삭제 : 메모리에서 없애버리는 것 

 

 

객체인지 확인

데이터 타입을 체크하는 방법은 typeof => 허술하다. (null, 배열 모두 object로 나옴)

정교하게 타입을 체크하는 방법 Object.prototype.toString.call <- 오브젝트의 부모에게 가서 toString이라는 함수를 빌려 쓴다. 

 

Object.prototype.toString.call([1,2,3])
>>[object Array] 이런 식으로 정확하게 배열인 것을 알려준다. 

 

 

Object.prototype.toString.call([1,2,3]).slice(8, -1)

 >> 결과값을 8번째부터, 뒤에서 1번째 까지 잘라준다.

 

key값, value값, entries 등등 연습 많이 해야된다. 

 

 

 

 

 

★배열 구조 분해 할당 ★ (엄청 중요)
배열이 들어오면, 배열의 변수 1, 배열의 변수 2로 뽑아서 쓸 수 있다. 

[Varialbe A, Variable B]  = Array; >> 배열의 순서대로 여기 할당되는 

배열의 순서는 바꿀 수 없다.

 

a1 은 10을 받고 100을 건너 띄고 싶을 떄 , , 이렇게 표시한다.

그 뒤로 모든 데이터는 rest 에 들어간다. 

rest의 결과

 

오브젝트는 배열로 뱉기 떄문에 key와 value를 배열값으로 받아서 처리해도 된다.

모든 키와 프로퍼티가 나온다. (순서는 못바꿈)

 

 

동일하게 span이라는 태그가 들어간 문장을 불러오는데, 

순서대로 first와 second로 만들어진 배열에 할당한다. 

 

이는 각각 first, second 변수에 들어가있는 것을 확인할 수 있다. 

 

 


let [a, b] = [10,20, 30, 40];
console.log(a,b);

a : 10 /  b : 20

 

 

 

객체 구조 할당 ★★★
순서가 상관이 없어서, 키값을 찾아간다. 
기본값을 지정할 수 있다! 
const salaries = {
    박지성 : 800,
    김보미 : 150,
    이경민 : 250,
    전희선 : 50,
}

const {박지성 , 김보미, 이경민, 전희선} = salaries;
console.log(박지성);

 

 

 

객체에서는 키값이 상관이 없기 때문에, 변수를 key값으로 두면 알아서 해당하는 key의 변수를 찾아간다! 

나열 순서가 달라지더라도 맞게 월급 값이 들어가는 것이다. 

 

 

만약 변수를 변경하고 싶다면 ? 

키값 : 변수명 ==> 이렇게 사용해서 변경하면 된다. 

 

 

기본값을 지정할 수 있다. 

 

 

 

 


function createUserList(options){

    const {name:n,age,address,phone,nickName = 'tiger'} = options;
   
    const name = '선범'
 
    return {
      name:n,
      age,
      address,
      phone,
      nickName
    }
  }
 
 
 
 
  // createUserList('seonbeom',30,'서울시 중랑구','010-2222-222')
 
 
  createUserList(
    {
      name:'tiger',
      age:35,
      address:'서울시 중랑구 면목동',
      phone:'010-2222-2222'
    }
  )

 


function createUserList(options){

    const {name:n,age,address,phone,nickName = 'tiger'} = options;
   
    const name = '선범'
 
    return {
      name:n,
      age,
      address,
      phone,
      nickName
    }
  }
 
 
 
 
  // createUserList('seonbeom',30,'서울시 중랑구','010-2222-222')
 
 
  createUserList(
    {
      name:'tiger',
      age:35,
      address:'서울시 중랑구 면목동',
      phone:'010-2222-2222'
    }
  )

 

 

 

 

<최종 정리> 

//1. 함수의 인수로 객체를 받아 처리할 수있다.
createUserList(
    {
      name:'tiger',
      age:35,
      address:'서울시 중랑구 면목동',
      phone:'010-2222-2222'
    }
  )


  //2. 함수 안에서 객체를 구조분해 할 수 있다.
function createUserList(options){

    const {name:n,age,address,phone,nickName = 'tiger'} = options;
   
    //3. 함수 스코프 안에 동일한 변수가 사용될 경우 rename할 수 있다. (alias)
    const name = '선범'
 

    //4. shorthand property
    return {
      name:n,
      age,
      address,
      phone,
      nickName
    }
  }
 
 
  // createUserList('seonbeom',30,'서울시 중랑구','010-2222-222')
 

  //5. 개량된 버전 : 어차피 들어오는게 객체라면 바로 인자에서 받아 구조분해 할당을 한다.

function createUserList({name:n, age, address, phone, nickname = 'tiger'}){

    const {} = options;
   
    //3. 함수 스코프 안에 동일한 변수가 사용될 경우 rename할 수 있다. (alias)
    const name = '선범'
 

    //4. shorthand property
    return {
      name:n,
      age,
      address,
      phone,
      nickName
    }
  }

 

 

 


참조복사, 얕은복사, 깊은복사

 

 

참조 복사

* 객체는 객체 자체를 복사하는 것이 아니라 객체의 참조값이 복사된다. 

 

얕은 복사

* for in 문을 사용해서 있는 데이터들을 복사한다. 

* assign메서드를 이용하여 여러 객체를 하나로 병합하는 예시

ㄴ 기존의 객체에 확장하는 case

ㄴ 빈객체를 넣고 user객체를 복사한다. 

 

 

깊은 복사

* 객체 안에 객체가 또 설정된 경우 얕은복사로는 안의 객체를 복사할 수 없다.

lodash로 구현할 수 있다. _.cloneDeep(obj)

 

 

<복사 실습>


// 객체 복사
// 1. for ~ in 문을 사용한 복사

const cloneObject = {};

for(let key in messenger) {
    cloneObject[key] = messenger[key];
}

console.log(cloneObject);

console.clear();



// 2. Object.assign()을 사용한 복사
const copyObject = Object.assign({}, messenger);
console.log(copyObject);

console.clear();



// 3. 전개 연산자(...)를 사용한 복사
const spreadObject = {...messenger};
console.log(spreadObject);

 

 

 

객체 병합
// 객체 병합(합성)
const cssMapA = {
  color: '#4b004b',
  margin: '0 auto',
};

const cssMapB = {
  display: 'flex',
  flexFlow: 'column',
  justifyContent: 'center',
  padding: '0.4em 0.62em',
  color: '#3f9e97',
};

const combinedCssMap = Object.assign({}, cssMapA, cssMapB);
console.log(combinedCssMap);

assign 메서드를 통해 두 객체를 새로운 객체에 이어준다. 

 

 

 

깊은 복사 함수

cloneDeep 함수는 전달받은 오브젝트를 인자로 전달받고, 

fromEntries는 배열의 key와 value 값의 쌍을 객체로 반환한다. 

ex) [['name', 'chaeyoung'], ['age', 29]]

 

인수로 전달받은 객체 object의 entries (값과 키의 배열) 를

map 메서드로 key와 value 를 확인하는데, 이 때 value 값이 객체인지 확인. (객체라면 2중 객체에 해당하는 것이므로) 

값이 있고 객체로 확인된다면 2중 객체를 재귀로 불러서 key와 value값을 배열로 리턴, 최종적으로는 객체로 리턴해준다. 

 

깊은 복사 끝!