for...in과 for...of는 for반복문의 사촌쯤되는 문법이다.
우선 둘의 핵심만 요약하자면
for...in : 객체
객체에 있는 심벌제외, enumberable한 프로퍼티를 순회할 때 사용.
배열이면 인덱스(0부터) 순회한다.
for...of : 배열
배열 안에 있는 요소를 하나하나 순회함. 객체에서 사용 불가.
배열 외에도 iterable한 특성이 있는 객체를 순회할 때 사용한다.(string)
for...in은 객체의 프로퍼티를 순회한다. 하지만 모든 프로퍼티를 순회하는 것은 아니고 symbol이 아닌 값, enumerable
한 프로퍼티만 순회한다. enumerable은 '열거가능한'
이란 뜻이다.
const obj = {name : "Tomi", age : 10};
for(const key in obj){
console.log(`${key} : ${obj[key]}`);
}
//name : Tomi
//age : 10
in 앞에 들어간 변수 key는 정해진건 아니고, 마음대로 지을 수 있다. 여기서는 key는 객체의 키값을, obj[key]는 키에 해당하는 값을 나타낸다.
let sum = 0;
let people = {
james : 20,
mina : 14,
yuri : 25,
}
for(const age in people){
sum += people[age];
}
console.log(sum); //59
위 예시는 for...in문으로 객체의 프로퍼티값을 sum에 계속 추가해서,
객체 안 사람들의 나이의 합을 구했다.
//Person이라는 생성자 함수를 정의했다
function Person(name,age) {
this.name = name;
this.age = age;
}
//prototype에 sayHi라는 메소드를 정의했다.
Person.prototype.sayHi = function sayHi(){
console.log(`hi my name is ${this.name}`);
}
//Jun이라는 Person의 인스턴스를 정의했다.
const Jun = new Person("Jun",20);
//for...in구문으로 Jun의 프로퍼티를 출력했다.
for(const Property in Jun){
console.log(Jun[Property]);
}
//결과
// Jun
// 20
// [Function: sayHi]
결과로 알 수 있는 것은 Jun의 고유 프로퍼티인 name,age뿐만 아니라 Person의 prototype에 들어있는 sayHi라는 메소드까지 출력되었다는 것이다.
좀 더 쉬운 예제를 보자
//Parnets라는 클래스 함수를 정의했다
class Parents {
//이 클래스로 형성된 인스턴스는 모두 kim이라는 firstname속성을 갖음.
constructor(){
this.firstName = "Kim";
}
}
//Parents의 프로토타입에 hair속성 추가했다
//이는 인스턴스의 고유 속성이 아니다.
Parents.prototype.hair = "black";
//rin이라는 인스턴스를 정의했다
const rin = new Parents();
//인스턴스에 나이 속성 추가
rin.age = 15;
//for...in반복문으로 인스턴스 rin의 프로퍼티를 출력
for(const key in rin){
console.log(`${key} : ${rin[key]}`);
//결과
// firstName : Kim
// age : 15
// hair : black
결과로 rin의 고유 프로퍼티 firstName,age 뿐만 아니라 부모의 프로토타입에 있는 hair속성 까지 출력되었다.
이는 for...in반복문이 상속받은 속성도 모두 순회한다는 것을 의미한다.
객체의 고유 속성만 출력하고 싶다면..
다음과 같이 객체명.hasOwnProperty
를 조건문으로 추가하자.
for(const ownKey in rin){
if(rin.hasOwnProperty(ownKey)){
//객체.hasOwnProperty(속성값)은 객체의 속성값이 자기소유인지를 t/f로 나타내준다.
console.log(`${ownKey} : ${rin[ownKey]}`);
}
}
//firstName : Kim
// age : 15
이제 rin이 가지고 있는 고유 속성만 추가되었다!
for...of은 array, arguments. nodeList, map ,set에서 쓰인다. 요약하자면 배열에서 많이 쓰이며, 객체에서는 사용이 불가능하다.
const arr = [1,2,3,4];
for(const item of arr){
console.log(item);}
//1 2 3 4
for...of은 string에서도 사용이 가능한데 이는 for...of가 iterable(반복가능한 : 이터러블)
한 객체에서 사용이 가능한 문법이기 때문이다. string또한 iterable한 특성 때문에 for..of로 순회가 가능하다.
let str = "hello";
for(let alphabet of str){
console.log(alphabet);
}
//h e l l o 한줄씩 나옴
let nums = [1,2,3,4,5,6,7,8,9];
for(const num of nums){
for(const num2 of nums){
console.log(`${num} x ${num2} = ${num*num2}`);}
}
for...in으로 구구단을 만들어 보았다!