Issue
온라인 강의 실행 컨텍스트에 대해서 알아보는 문제가 주어졌다.
// 가장 아래의 코드가 실행 되었을 때, “Passed ~” 가 출력되도록 getAge 함수를 채워주세요
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);
// 출력의 결과를 제출해주세요, 그리고 그 이유를 최대한 상세히 설명해주세요
var fullname = 'Ciryl Gane'
var fighter = {
fullname: 'John Jones',
opponent: {
fullname: 'Francis Ngannou',
getFullname: function () {
return this.fullname;
}
},
getName: function() {
return this.fullname;
},
getFirstName: () => {
return this.fullname.split(' ')[0];
},
getLastName: (function() {
return this.fullname.split(' ')[1];
})()
}
console.log('Not', fighter.opponent.getFullname(), 'VS', fighter.getName());
console.log('It is', fighter.getName(), 'VS', fighter.getFirstName(), fighter.getLastName);
Try&Error
첫번째 문제는 Object의 얕은 복사와 깊은 복사, 또는 새로운 객체 생성하는 방법에 대한 문제이다. 단순하게 새로운 함수를 정의한 다음 기존 user를 대입해버리면 객체의 주소값이 복사되므로, 두 유저의 값이 같게 되고, 어느 한쪽의 값만 수정할 수 없게 되기 때문에 원하는 결과를 얻을 수 없게 된다. 그러므로 새로운 객체를 선언하고, 새 객체의 요소와 값을 입력하는 방법으로 해결해야 한다.
두번째 문제는 this 바인딩 문제이다. 객체 내에서 사용되는 this가 어디에 연결되는지에 대한 것으로, 함수 표현식 중 function키워드를 사용하는 경우와 화살표 함수의 차이, 익명함수(즉시실행함수)에 대한 this 바인딩 차이를 알 수 있는 문제이다.
Solution
첫번째 문제에서 나는 newUser를 new Object로 새로운 객체를 만들고, key와 value를 entries로 불러와 넣어주었다.
var user = {
name: "john",
age: 20,
}
var getAged = function (user, passedTime) {
let newUser = new Object
for (let [key, value] of Object.entries(user)) {
newUser[key] = value
}
newUser.age += passedTime
return newUser
}
var agedUser = getAged(user, 6);
console.log(agedUser)
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");
}
}
console.log(agedUserMustBeDifferentFromUser(user, agedUser))
답안은 조금 달랐는데, var 키워드와 {}로 객체를 만들고, property만 for in 으로 불러와 값은 user에 key를 이용해 입력했다.
var user = {
name: "john",
age: 20,
}
// 객체 만들어 프로퍼티 복사하기
var getAged = function (user, passedTime) {
var result = {};
for (var prop in user) {
result[prop] = user[prop];
}
result.age += passedTime;
return result;
}
var agedUser = getAged(user, 6);
var agedUserMustBeDifferentFromUser = function (user1, user2) {
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);
두번째 문제의 결과는
// Not Francis Ngannou VS John Jones
// It is John Jones VS Ciryl Gane
인데, 당연한 결과이고 그 이유에 대해 서술하는 것이 문제이므로 적어보면,
this 가 어디에 바인딩 되느냐에 따라 결과가 달라지는 결과로, 가장 먼저 fighter.opponent.getFullname() 의 경우, this는 상위 object인 oppenent에 바인딩 되어있어서, this.fullname은 Francis Ngannou가 반환된다. 그 다음 fighter.getName()의 this는 함수 선언으로 생성된 요소이므로 this는 상위 객체인 fighter에 바인딩 되어, fullname은 John Jones가 됩니다.
마지막 fighter.getFirstName()과 fighter.getLastName()은 화살표 함수, 그리고 즉시실행 익명함수로 선언되어 있기 때문에 this 는 fighter 객체의 상위 객체 즉, 전역객체인 window에 바인딩 되고, 전역 변수로 선언한 fullname인 Ciryl Gane가 반환됩니다.
Learned
this 바인딩은 혼동되기 쉬운 개념이다. bind를 시켜주거나, 그 개념에 대해 잘 정리한 여러 설명글을 읽으며 자연스럽게 읽히도록 반복해서 살펴봐야한다.
참조하면 좋은 영상
1. 별코딩 This 와 Bind
2. 우테코 브콜의 This
'daily' 카테고리의 다른 글
23.04.14. programmers 코딩테스트 문제 풀기[0] (0) | 2023.04.15 |
---|---|
23, 15주차 (0) | 2023.04.13 |
23.04.12. 혼자 공부하는 자바스크립트 확인문제 풀이 기록[1] (0) | 2023.04.12 |
23, 13~14주차 (0) | 2023.04.09 |
23.04.07. JS 기본 문법 연습 (0) | 2023.04.07 |