개요
- 개요는 시리즈 1과 동일
- 이하에서는 for문과 forEach문에 대해 구체적으로 정리함
1. 문법
for (let j = 0; j < keypoints.length; j++) {
let x = keypoint.x - 320;
let y = keypoint.y - 240;
console.log(`${keypoint.name}: [${x}, ${y}]`);
}
res.keypoints.forEach((keypoint) => {
let x = keypoint.x - 320;
let y = keypoint.y - 240;
console.log(`${keypoint.name}: [${x}, ${y}]`);
})
2. 비교
|
for문 |
forEach문 |
장점 |
- 인덱스 제어 가능 - break, continue 사용 가능 - 배열 뿐만 아니라 객체의 속성에 대해서도 순회 가능 |
- 가독성 향상 |
단점 |
- 가독성 떨어짐 |
- 인덱스 제어 불가 - break, continue 사용 불가 (반복문을 보다 효율적으로 만들어주는 구성 요소) - 일반적으로 객체의 속성 순회 어려움 |
// 객체
const myObject = {
name: 'John',
age: 25,
city: 'New York',
gender: 'Male'
};
// 배열
const myArray = ['name', 'age', 'city', 'gender']
- 객체 = myObject, 객체는 key-value로 이루어져 있음, 따라서 객체의 속성 = value = John, 25, New York, Male을 의미함
- 그러나 forEach 문은 배열을 순회하기에는 적합하지만, 객체의 속성까지 순회 불가
: forEach 메서드는 처리 대상으로 배열을 기대, 그러나 객체는 key-value 쌍의 집합
- 보완책
- 객체의 key들을 배열로 얻기 → 각 key에 대응하는 value에 접근
// Object.keys() 사용
const keys = Object.keys(myObject);
keys.forEach(key => {
console.log(`${key}: ${myObject[key]}`);
});
// 프로젝트에 적용
const FINGER_INDICES = {
thumb: [0, 1, 2, 3, 4],
indexFinger: [0, 5, 6, 7, 8],
middleFinger: [0, 9, 10, 11, 12],
ringFinger: [0, 13, 14, 15, 16],
pinky: [0, 17, 18, 19, 20],
};
Object.keys(FINGER_INDICES).forEach(finger => {
const points = FINGER_INDICES[finger].map(idx => res.keypoints[idx]);
this._drawPath(ctx, points, false);
});
2. 배열 요소가 객체인 경우, 배열을 순회하면서 객체의 속성에 접근
( 1-1의 객체의 key들을 배열로 얻는 과정 생략하여 보다 직관적인 방법 )
/** this._result의 형태
this._result:
0:
box: {xMin: 133.~, yMin: 140.~, xMax: 346.~, yMax: 391.~, width: 213.~}
keypoints: Array(468)
[0 ... 99] //배열 요소가 객체
0: {x: 193.~, y: 315.~, z: -33.~, name: 'lips'}
1: ... 반복
2: ...
3: ...
**/
this._result = result;
this._result.forEach((res, i) => {
res.keypoints.forEach((keypoint) => { //res.keypoints는 배열, 배열의 각 요소(keypoint)에 대해 순회, i는 현재 요소의 인덱스
if (keypoint.name != undefined) {
let x = keypoint.x - 320; //keypoint.x 및 keypoint.y 를 사용하여 현재 요소의 속성에 접근
let y = keypoint.y - 240;
console.log(`${keypoint.name}: [${x}, ${y}]`);
}
})
})
3. for…in 문 사용
- 객체의 모든 속성에 대해 반복
- 그러나 hasOwnProperty 를 이용하여 객체 자체의 속성인지 확인하는 것이 중요
- 즉 프로토타입 체인을 따라 올라가서 속성을 가져오지 않고, 해당 객체의 속성에서만 확인하기 위함
- for…in 문과 형태가 유사한 for…of 문은 이터러블 객체를 순회하는 데에 유용함.
( 이터러블 객체 : 여러 내장 객체. Array, String, Map, Set )
- 그러나 객체는 원칙적으로 이터러블 객체가 아님. 단지 객체 내부에 배열이 있을 수 있는 것 뿐임
// for...in 문 적용
for (let key in myObject) {
if (myObject.hasOwnProperty(key)) {
console.log(`${key}: ${myObject[key]}`);
}
}
// 이터러블 객체에 for...of 문 적용
const myString = "Hello";
for (const char of myString) {
console.log(char);
}
const myMap = new Map([
['key1', 'value1'],
['key2', 'value2'],
['key3', 'value3']
]);
for (const [key, value] of myMap) {
console.log(`${key}: ${value}`);
}
const mySet = new Set([1, 2, 3, 4, 5]);
for (const element of mySet) {
console.log(element);
}