Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 값으로 객체의 키 검색하기 – keysOf() 메서드 구현 방법

JavaScript 개발을 하다 보면 중첩된 객체 안에서 특정 값을 가진 키(key)가 무엇인지 찾아야 하는 경우가 종종 있습니다. 이 글에서는 임의의 깊이까지 중첩된 객체를 탐색하여, 지정한 값과 일치하는 모든 키를 배열로 반환하는 Object.prototype.keysOf() 메서드를 직접 구현하는 방법을 알아보겠습니다.

문제 정의

다음과 같은 객체가 있다고 가정해 봅시다.

const obj = {
  "name": "Vivek Sharma",
  "occupation": "Software Engineer",
  "age": 23,
  "contacts": [{
    "name": "Mukul Sharma",
    "occupation": "Software Engineer",
    "age": 31,
  }, {
    "name": "Jay Sharma",
    "occupation": "Software Engineer",
    "age": 27,
  }, {
    "name": "Rajan Sharma",
    "occupation": "Software Engineer",
    "age": 32,
  }]
};

위 예제는 한 단계까지만 중첩되어 있지만, 실무에서는 훨씬 더 깊은 구조의 객체를 다루는 경우도 많습니다. 우리의 목표는 이런 객체 어디에 있든 지정한 값을 가진 모든 키를 찾아내는 것입니다.

keysOf() 메서드 구현하기

구현의 핵심 아이디어는 다음과 같습니다.

  • Object.keys()로 현재 객체의 모든 키를 가져옵니다.
  • 각 키의 값이 찾고자 하는 값과 일치하면(=== 엄격 비교) 결과 배열에 해당 키를 추가합니다.
  • 값이 객체이면서 배열이 아니라면, 재귀 호출을 통해 내부 프로퍼티까지 계속 탐색합니다.

전체 코드

const obj = {
  "name": "Vivek Sharma",
  "occupation": "Software Engineer",
  "age": 23,
  "contacts": [{
    "name": "Mukul Sharma",
    "occupation": "Software Engineer",
    "age": 31,
  }, {
    "name": "Jay Sharma",
    "occupation": "Software Engineer",
    "age": 27,
  }, {
    "name": "Rajan Sharma",
    "occupation": "Software Engineer",
    "age": 32,
  }]
};

const keysOf = function(val, obj = this, res = []){
  const keys = Object.keys(obj);
  for(let ind = 0; ind < keys.length; ind++){
    if(obj[keys[ind]] === val){
      res.push(keys[ind]);
    } else if(typeof obj[keys[ind]] === 'object' &&
      !Array.isArray(obj[keys[ind]])){
      keysOf(val, obj[keys[ind]], res);
    }
  }
  return res;
};
Object.prototype.keysOf = keysOf;
console.log(obj.keysOf(23));

함수 시그니처를 살펴보면, val은 찾고자 하는 값, obj는 탐색 대상 객체(기본값은 this, 즉 메서드를 호출한 객체), res는 결과를 누적할 배열입니다. 기본 매개변수(default parameter)를 활용하면 재귀 호출 시 별도의 초기화 없이 하나의 결과 배열을 계속 공유할 수 있습니다.

실행 결과

콘솔에는 다음과 같이 출력됩니다.

['age']

obj.keysOf(23)을 호출하면 값이 23인 키 'age'가 배열에 담겨 반환됩니다. 참고로 contacts는 배열이므로 Array.isArray() 체크에 의해 재귀 탐색 대상에서 제외됩니다. 만약 배열 요소 내부까지 탐색하고 싶다면 해당 조건을 제거하거나 수정하면 됩니다.