freeCodeCamp의 문제들은 타 문제제공 사이트들에 비해 난이도가 낮은 편이고, 개념설명도 동시에 되어 있어 초급자에게 가장 적합한 문제들이 아닐까싶다.
개인적으로 기초가 더 보완되어야 하는 상태라고 판단해 Basic JavaScript 문제를 풀어보았다.
문제출처: freecodecamp.org
We have an array of objects representing different people in our contacts lists.
A lookUpProfile function that takes name and a property (prop) as arguments has been pre-written for you.
The function should check if name is an actual contact's firstName and the given property (prop) is a property of that contact.
If both are true, then return the "value" of that property.
If name does not correspond to any contacts then return "No such contact".
If prop does not correspond to any valid properties of a contact found to match name then return "No such property".
⇨ 즉, contacts 배열 속 객체들 안에 "firstName"의 값으로 매개변수로 주어진 name이 있는지, 또 각 객체의 key로 매개변수 prop과 일치하는 프로퍼티가 객체 내에 존재하는 지 여부를 확인하고, 있다면 그 값을 반환해야 하는 문제.
없을 경우 각각 "No such contact"와 "No such property"를 반환해야한다.
var contacts = [
{
"firstName": "Akira",
"lastName": "Laine",
"number": "0543236543",
"likes": ["Pizza", "Coding", "Brownie Points"]
},
{
"firstName": "Harry",
"lastName": "Potter",
"number": "0994372684",
"likes": ["Hogwarts", "Magic", "Hagrid"]
},
{
"firstName": "Sherlock",
"lastName": "Holmes",
"number": "0487345643",
"likes": ["Intriguing Cases", "Violin"]
},
{
"firstName": "Kristian",
"lastName": "Vos",
"number": "unknown",
"likes": ["JavaScript", "Gaming", "Foxes"]
}
];
첫 오답은 다음과 같다.
function lookUpProfile(name, prop){
// Only change code below this line
for(let i = 0; i < 4; i++) {
if(contacts[i][0] === name){
return contacts[i][0];
} else {
return "No such contact";
}
for(let n = 0; n < 4; n++) {
if(contacts[i][n] === prop) {
return contacts[i][n];
} else {
return "No such property";
}
}
}
// Only change code above this line
}
... 부분적으로만 맞다고 알려준다.
그래... 코드는 거짓말을 하지 않지......
if(contacts[i][n] === prop)
이렇게 index를 연속으로 이어붙이면 contacts 배열 i번째 객체에서 n번째 인덱스 값을 반환해주겠지....라고 생각했던 것
그런데 막상 console창에 찍어보니
이렇게는 반환해주지 않는다...🥺
도대체 이런 없는 문법을 만들어내는 창의력은 자꾸 어디서 나오는걸까?
객체의 프로퍼티 value에 접근할 때는 프로퍼티 key에 마침표 표기법이나 대괄호 표기법을 이용해야 하는 것을...
예를 들어 "Harry"라는 값을 반환받기 위해 contacts[1][0];
를 하면 undefined
를 반환하지만,
contacts[1]["firstName"];
라고 하면 정상적으로 "Harry"
를 반환한다.
Get Help
의 도움을 받아 정답과 오답을 비교해본다.
<Passed 된 답변>
function lookUpProfile(name, prop){
// Only change code below this line
for(let i = 0; i < contacts.length; i++) {
if(contacts[i].firstName === name){
if(contacts[i][prop]) {
return contacts[i][prop];
} else {
return "No such property";
}
}
}
return "No such contact";
}
// Only change code above this line
if(contacts[i][0] === name)
이 코드는 contacts 배열의 i번째의 객체의 0번째 인덱스를 접근하고 있다. 하지만 contacts[i]
의 결과는 객체이기 때문에 이 객체의 프로퍼티명이 0인 값을 접근하려는 의도가 아니였다면 이 코드는 틀린표현이다. 각 객체는 모두 "firstName" 프로퍼티를 갖고 있으므로 if(contacts[i].firstName === name)
이 코드가 올바른 표현이다. if(contacts[i][n] === prop)
코드는 contacts[i]의 결과가 배열인 것처럼 for문을 순회하며 값을 접근하고 있다. 이는 잘못된 코드이다. contacts[i]의 결과는 객체이기 때문에, if(contacts[i][prop])
와 같은 코드로 접근하는 것이 옳다. i < 4;
라고 적었지만i < contacts.length;
로 바꿔준다. contacts[0][0]
는 undefined, contacts[0]["lastName"]
은 "Laine"을 반환. 객체의 프로퍼티 값 접근은 마침표 표기법(.)이나 대괄호 표기법([])을 이용해 key로 할 것! (+프로퍼티 키는 문자열이므로 일반적으로 따옴표""를 사용) .hasOwnProperty("프로퍼티")
메소드를 사용해서 if(contacts[i].hasOwnProperty(prop))
로 조건문을 기재하는 방법도 있다.("프로퍼티" in 객체명);
이 있다.hasOwnProperty
와 in
의 차이는 in
은 prototype chain의 상속된 속성까지도 반환해준다는 것이다. 만일 원 객체 속 프로퍼티 존재여부만을 확인할 때는 hasOwnProperty
를 사용하는 것이 적절하다.