자바스크립트 강의

[JavaScript] 3주차 - 과제 수행 (불변 객체(얕은 복사), this)

notion0896 2024. 10. 14. 15:50

1. user가 나이를 몇살 먹었는지에 따라 user, agedUser를 비교하는 문제

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 user = {
    name: "john",
    age: 20,
}

var getAged = function (user, passedTime) {
	var newUser = user;
    newUser.age += passedTime;
    
    return newUser; 
} 
// 이렇게 단순히 하게되면 newUser는 user의 값을 복사해오는건 맞지만 
나중에 user안의 값이 바뀌게 되면 newUser의 값도 똑같이 바뀌게 된다. 


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);

 

그렇다면 어떻게 바꿔야 할까?

 

for(~ in ~)문을 활용해 얕은 복사를 통해 newUser에서 age의 값을 변경해보자.

var user = {
  name: "john",
  age: 20,
};

var getAged = function (user, passedTime) {

  //객체는 직접 값을 저장하는게 아니라 별도의 저장한 공간의 주소를 가져오는 방식, 
  //즉 참조형이기 때문에 이렇게 가져오게 되면 똑같은 값을 갖게된다.
  //그래서 우리에게 필요한건 순회하면서 아예 새로운 객체를 만들어 주는 것.

  var newUser = {}; // 먼저 newUser라는 빈 객체를 만들어 준다.
  
  for (var property in user) {
    newUser[property] = user[property];
  } // for in 문을 활용해 user의 프로퍼티와 newUser의 프로퍼티를 복사해 같게 만든다.

  newUser.age += passedTime; // 그런 다음 newUser의 age값이 passedTime의 값에 따라 더해지도록 한다.

  return newUser; // newUser를 리턴한다. 
};

var agedUser = getAged(user, 6);

var agedUserMustBeDifferentFromUser = function (user1, user2) {

    console.log(user1) // { name: "john", age: 20, };
    console.log(user2) // { name: "john", age: 26, };

  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);
// "Passed! If you become older, you will be different from you in the past!"

2. 콘솔로 찍었을 때 각각 어떤 값이 나오는지 유추해보기

 

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);
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);


//fighter.opponent.getFullname() 
=> fighter.opponent.라는 확실한 객체를 지목했기 때문에 
메서드에 해당한다. 즉 여기서 this는 Francis Ngannou를 지칭.


//fighter.getName() 
=> 이것도 fighter 라는 명확한 호출의 주체를 갖고 있기 때문에 여기서 this는 fighter의
fullname 요소에 해당하는 John Jones를 지칭.


//fighter.getFirstName() 
=> 여기서  getFirstName는 화살표 함수이다. 화살표 함수는 this를 바인딩하지 
않기 때문에 this는 fighter안에 있는 객체가 아닌 전역 객체인 var fullname = 'Ciryl Gane'의 [0]번째 값
즉 Ciryl를 지칭.


// fighter.getLastName 
=> 여기서 주목할 점은 fighter.getLastName()가 아닌 fighter.getLastName를 호출했다는 점이다. 
'fighter.getLastName()' 이 상태였다면 호출이 이미 끝난 함수를 불러오는 것이지만,
'fighter.getLastName' 이 상태는 호출이 이미 끝난 함수를 호출하는것이 아니라 'fighter.getLastName'이라는
함수를 그냥 '콜했다' 라고 볼 수 있다.

getLastName은 함수를 선언하고 호출까지 됐다고 봐야하지만 호출까지만 하고 하무것도 리턴하지 않았기때문에
this를 바인딩했다고 볼 수 없다.
그렇기때문에 getLastName에서 this는 전역 객체인 var fullname = 'Ciryl Gane'의 [1]번째 값,
즉 Gane을 지칭하는 것.