예비
JavaScript에는 여러 값을 포함 할 수있는 하나의 데이터 유형 ( Object) 만 있습니다. 배열 객체의 특별한 형태이다.
(일반) 물체의 형태는
{key: value, key: value, ...}
배열의 형태는
[value, value, ...]
배열과 객체 모두 key -> value
구조를 노출합니다 . 배열의 키는 숫자 여야하지만 모든 문자열은 객체의 키로 사용할 수 있습니다. 키-값 쌍은 "properties" 라고도합니다 .
점 표기법을 사용하여 속성에 액세스 할 수 있습니다
const value = obj.someProperty;
또는 괄호 표기 , 속성 이름이 유효한 JavaScript 않을 것인지 식별자 이름 [사양] 또는 이름 변수 값이다 :
// the space is not a valid character in identifier names
const value = obj["some Property"];
// property name as variable
const name = "some Property";
const value = obj[name];
이런 이유로 배열 요소는 대괄호 표기법을 통해서만 액세스 할 수 있습니다.
const value = arr[5]; // arr.5 would be a syntax error
// property name / index as variable
const x = 5;
const value = arr[x];
잠깐만 ... JSON은 어떻습니까?
JSON은 XML, YAML, CSV 등과 같은 텍스트의 텍스트 표현입니다. 이러한 데이터로 작업하려면 먼저 배열 및 객체와 같은 JavaScript 데이터 유형으로 변환해야합니다 (그리고 이러한 작업을 수행하는 방법은 방금 설명했습니다). JSON을 구문 분석하는 방법 은 JavaScript에서 JSON 구문 분석 질문에 설명되어 있습니다 . .
추가 자료
배열과 객체에 액세스하는 방법은 기본적인 JavaScript 지식이므로 MDN JavaScript 안내서 , 특히 섹션 을 읽는 것이 좋습니다.
중첩 된 데이터 구조에 액세스
중첩 된 데이터 구조는 다른 배열 또는 객체를 참조하는 배열 또는 객체입니다. 즉, 값은 배열 또는 객체입니다. 도트 또는 브래킷 표기법을 연속적으로 적용하여 이러한 구조에 액세스 할 수 있습니다.
예를 들면 다음과 같습니다.
const data = {
code: 42,
items: [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}]
};
name
두 번째 항목 에 액세스하려고한다고 가정 해 봅시다 .
다음은 단계별로 수행 할 수있는 방법입니다.
우리가 볼 수 있듯이 data
객체는 점 표기법을 사용하여 속성에 액세스 할 수 있습니다. items
속성은 다음과 같습니다 액세스 할 수 있습니다 :
data.items
값은 배열이며, 두 번째 요소에 액세스하려면 대괄호 표기법을 사용해야합니다.
data.items[1]
이 값은 객체이며 점 표기법을 다시 사용하여 name
속성 에 액세스합니다 . 결국 우리는 다음을 얻습니다.
const item_name = data.items[1].name;
또는 이름에 점 표기법 사용에 유효하지 않은 문자가 포함 된 경우 속성에 대괄호 표기법을 사용할 수 있습니다.
const item_name = data['items'][1]['name'];
속성에 액세스하려고하는데 undefined
다시 돌아 오나요?
대부분의 경우 undefined
객체 / 어레이에는 해당 이름의 속성이 없습니다.
const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined
객체 / 배열의 구조를 사용 console.log
하거나 console.dir
검사하십시오. 액세스하려는 속성이 실제로 중첩 된 객체 / 배열에 정의되어있을 수 있습니다.
console.log(foo.bar.baz); // 42
속성 이름이 동적이고 미리 알 수 없으면 어떻게합니까?
속성 이름을 알 수 없거나 배열의 객체 / 요소에 대한 모든 속성에 액세스하려는 경우 객체에 for...in
[MDN] 루프를 사용하고 배열에 for
[MDN] 루프를 사용하여 모든 속성 / 요소를 반복 할 수 있습니다.
사물
의 모든 속성을 반복하기 위해 다음과 같이 객체를data
반복 할 수 있습니다 .
for (const prop in data) {
// `prop` contains the name of each property, i.e. `'code'` or `'items'`
// consequently, `data[prop]` refers to the value of each property, i.e.
// either `42` or the array
}
객체의 위치와 수행하려는 작업에 따라 속성이 실제로 객체의 속성인지 아니면 상속 된 속성인지 각 반복에서 테스트해야 할 수도 있습니다. Object#hasOwnProperty
[MDN]으로 이를 수행 할 수 있습니다 .
for...in
with 대신에 [MDN] 을 hasOwnProperty
사용 하여 속성 이름 배열 을 얻을 수 있습니다 .Object.keys
Object.keys(data).forEach(function(prop) {
// `prop` is the property name
// `data[prop]` is the property value
});
배열
data.items
배열 의 모든 요소를 반복 하기 위해 for
루프를 사용합니다 .
for(let i = 0, l = data.items.length; i < l; i++) {
// `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
// we can access the next element in the array with `data.items[i]`, example:
//
// var obj = data.items[i];
//
// Since each element is an object (in our example),
// we can now access the objects properties with `obj.id` and `obj.name`.
// We could also use `data.items[i].id`.
}
for...in
배열을 반복 하는 데 사용할 수도 있지만 이것을 피해야하는 이유가 있습니다. 배열에서 'for (var item in list)'가 JavaScript에서 나쁜 습관으로 간주되는 이유는 무엇입니까? .
ECMAScript 5의 브라우저 지원이 증가함에 따라 배열 방법 forEach
[MDN]도 흥미로운 대안이되었습니다.
data.items.forEach(function(value, index, array) {
// The callback is executed for each element in the array.
// `value` is the element itself (equivalent to `array[index]`)
// `index` will be the index of the element in the array
// `array` is a reference to the array itself (i.e. `data.items` in this case)
});
ES2015 (ES6)를 지원하는 환경에서는 [MDN] 루프 를 사용할 수도 있습니다. [MDN] 루프는 배열뿐만 아니라 반복 가능한 작업 에도 사용할 수 있습니다 .for...of
for (const item of data.items) {
// `item` is the array element, **not** the index
}
각 반복 for...of
에서 iterable의 다음 요소를 직접 제공하며 액세스하거나 사용할 "인덱스"가 없습니다.
데이터 구조의 "깊이"를 모르면 어떻게해야합니까?
알 수없는 키 외에도 데이터 구조의 "깊이"(예 : 중첩 된 개체 수)도 알 수 없습니다. 깊이 중첩 된 속성에 액세스하는 방법은 일반적으로 정확한 데이터 구조에 따라 다릅니다.
데이터 구조는 예를 들면 이진 트리의 표현의 반복 패턴을 포함하지만, 일반적으로 용액에 포함 재귀 [위키] 상기 데이터 구조의 각 레벨 액세스.
다음은 이진 트리의 첫 번째 리프 노드를 가져 오는 예입니다.
function getLeaf(node) {
if (node.leftChild) {
return getLeaf(node.leftChild); // <- recursive call
}
else if (node.rightChild) {
return getLeaf(node.rightChild); // <- recursive call
}
else { // node must be a leaf node
return node;
}
}
const first_leaf = getLeaf(root);
const root = {
leftChild: {
leftChild: {
leftChild: null,
rightChild: null,
data: 42
},
rightChild: {
leftChild: null,
rightChild: null,
data: 5
}
},
rightChild: {
leftChild: {
leftChild: null,
rightChild: null,
data: 6
},
rightChild: {
leftChild: null,
rightChild: null,
data: 7
}
}
};
function getLeaf(node) {
if (node.leftChild) {
return getLeaf(node.leftChild);
} else if (node.rightChild) {
return getLeaf(node.rightChild);
} else { // node must be a leaf node
return node;
}
}
console.log(getLeaf(root).data);
알 수없는 키와 깊이로 중첩 된 데이터 구조에 액세스하는보다 일반적인 방법은 값의 유형을 테스트하고 그에 따라 조치하는 것입니다.
다음은 중첩 된 데이터 구조 내의 모든 기본 값을 배열에 추가하는 예입니다 (함수를 포함하지 않는다고 가정). 객체 (또는 배열)가 발생하면 toArray
해당 값을 다시 호출 합니다 (재귀 호출).
function toArray(obj) {
const result = [];
for (const prop in obj) {
const value = obj[prop];
if (typeof value === 'object') {
result.push(toArray(value)); // <- recursive call
}
else {
result.push(value);
}
}
return result;
}
const data = {
code: 42,
items: [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}]
};
function toArray(obj) {
const result = [];
for (const prop in obj) {
const value = obj[prop];
if (typeof value === 'object') {
result.push(toArray(value));
} else {
result.push(value);
}
}
return result;
}
console.log(toArray(data));
헬퍼
복잡한 객체 또는 배열의 구조가 반드시 명확하지는 않기 때문에 각 단계의 값을 검사하여 더 나아가는 방법을 결정할 수 있습니다. console.log
[MDN] 및 console.dir
[MDN] 이이 작업을 도와줍니다. 예를 들어 (Chrome 콘솔의 출력) :
> console.log(data.items)
[ Object, Object ]
여기서 우리 data.items
는 이것이 두 객체 인 두 개의 요소를 가진 배열 임을 알 수 있습니다. Chrome 콘솔에서 개체를 즉시 확장하고 검사 할 수도 있습니다.
> console.log(data.items[1])
Object
id: 2
name: "bar"
__proto__: Object
이는 우리에게 data.items[1]
객체이며, 확장 후 우리가 세 가지 속성을 가지고 있음을 볼 수 id
, name
과 __proto__
. 후자는 객체의 프로토 타입 체인에 사용되는 내부 속성입니다. 그러나 프로토 타입 체인과 상속은이 답변의 범위를 벗어납니다.