데이터 저장 방식 관련(객체)
var user = {
name: "john",
age: 20,
}
var getAged = function (user, passedTime) {
// 여기를 작성해 주세요!
}
var agedUser = getAged(user, 6);
var agedUserMustBeDifferentFromUser = function (user1, user2) {
if (!user2) {
console.log("Failed! user2 doesn't exist!");
} else if (user1 !== user2) {
console.log("Passed! If you become older, you will be different from you in the past!")
} else {
console.log("Failed! User same with past one");
}
}
agedUserMustBeDifferentFromUser(user, agedUser);
위는 과제로 나온 코드이다.
getAged 함수를 통하여 user보다 6살이 많은 새로운 객체 값을 만들어 내는 것이 목표였다.
그래서 간단하게 getAged함수 내부를 다음과 같이 짜보았다.
var getAged = function (user, passedTime) {
var user2 = user
user2.age += passedTime
return user2
}
user2 객체에 user를 복사해준 후 .age 프로퍼티에 접근하여 passedTime만큼 더해주는 내용이었는데 예상과 다르게 "Failed! User same with past one"문구가 출력되었다.
확인해보니 객체의 데이터 저장 방식과 관련된 상황이었다.
객체를 복사해오는 시점에서 원본 객체(user)와 같은 주소 값을 복사해오는데,
그 후 age 값에 접근하여 데이터를 변경해주었기 때문에 같은 주소를 공유하는 user의 age값도
동일하게 변경되어버린 것이다.
즉 user와 동일한 주소값을 부여해주는 것이 아니라 새로 주소값을 부여해 줄 필요가 있었다.
var getAged = function (user, passedTime) {
var user2 = {};
for (info in user){
user2[info] = user[info]
}
user2.age += passedTime
return user2
}
해결 방법으로 user2에 user 객체를 대입해주는 것이 아니라
for in 문을 통해 같은 값으로 새로운 객체를 생성해주었다.
객체와 배열 등 주소 자체를 복사해오는 경우에 단순 대입 처리를 하면 이후 값 변경에서 원본까지 변경되는 불상사가 발생한다는 것을 알게 되었다.
비슷한 문제를 처리할 때 새로운 객체, 배열을 생성해주고 그렇게 생성된 것에 대하여 수정을 해주는 방식을 택할 필요가 있는걸 알게되었다.
호이스팅 관련
var a = 1;
function outer() {
function inner() {
console.log(a);
var a = 3;
}
inner();
console.log(a);
}
outer();
console.log(a);
다음과 같은 코드에서 가장 상단에 var a = 1;을 선언 및 할당을 해주었으므로
실행을 했을 경우
1
1
1
이 찍힐거라는 생각을 했다.
하지만 실제 실행 결과는
undefined
1
1
의 결과값이 나왔다.
예측과 결과값이 달랐던 이유는 '호이스팅' 때문이었는데,
실행 컨텍스트 내에서 특히 LE(LexicalEnvironment)의 record(식별자 정보)를 수집하는 방식이 '호이스팅'이라고 칭하는데
간단하게 설명하자면, 선언부를 가장 상단에서 선언 한 후에
데이터 값을 할당하는 형식으로 이해했다.
function inner() {
console.log(a);
var a = 3;
}
문제가 되었던 inner() 함수를 보면 console.log(a);의 아래에 var a = 3;이 적혀있다.
따라서 먼저 찍히는 a로그는 전역부분에서 선언한 1이 찍힐거라 예상했으나
위 코드를 풀어서 적어보자면 아래와 같다.
function inner() {
var a;
console.log(a);
a = 3;
}
즉 a라는 변수명을 먼저 선언해주었기에 console.log(a)가 undefined으로 나타난 것이다.
호이스팅에 대한 지식이 없다면 직관적으로 순서가 받아들여지지 않는 부분이라 헷갈리는 점이 컸다.
inner()함수 처럼 간단하게 되어있으면 괜찮겠지만
값이 중첩되는 경우, 복잡해질 경우 구조 파악에 신경을 써야할 것 같다. var경우 변수명이 겹쳐서 필요한 값이 undefined처리 되거나 하는 문제가 생기므로, 가급적 변수명은 겹치지 않게.. 하는 노력도 필요할 것 같다.