JavaScript 문법 종합반 3주차 - 과제

반응형

문제 1


나이든 유저
가장 아래 코드가 실행되었을때, “Passed ~” 가 출력되도록 getAge 함수를 채워주세요

 

문제가 댕강.. 설명이 없어서 어떤것을 원하는 문제인지 몰랐는데 알고보니 user 객체와 getAged 함수를 비교하고 서로 다르게 해서 원하는 결과를 내는 문제였다..!

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

 

만약, user 객체를 새로운 변수에 저장하고 새로운 변수를 통해 age값을 가져와서 값을 수정하면 둘다 똑같이 적용이된다. 이는  객체는 참조형을 쓰고 있기때문에 결과 값이 같게 나올 수 밖에 없기 때문이다. 어떻게 하면 불러오되 각각 다른 값들을 낼 수 있을까?

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

var getAged = function (user, passedTime) {
	var newUser = user;
    newUser.age += passedTime;
    
    return 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);

 

 

객체는 여러 값들을 포함할 수 있는 하나의 덩어리이며 참조타입(reference type) 이라 부른다.

프로퍼티는 키-값 쌍으로 구성되는데 키는 값을 나타내는 이름이라 생각하면 되고, 이 키로 해당 프로퍼티 값에

접근할 수 있다.

 

for문을 이용해서 user 객체를 프로퍼티 채로 새로운 객체를 만들어 저장하도록 한 후, 그 객체의 값을 변경해주면 서로 영향을 주지 않고 값을 수정해서 적용시킬 수 있다.

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

var getAged = function (user, passedTime) {
    var obj = {};
    for (var prp in user) {
        obj[prp] = user[prp];
    }
    obj.age += passedTime; 
    return obj;
}


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

 

 

문제 2


어떤 매치가 성사될까?
출력의 결과를 제출해주세요, 그리고 그 이유를 최대한 상세히 설명해주세요주의사항 : 브라우저에서 테스트해주세요(Chrome → 개발자 도구 → 콘솔에 입력하여 실행)

 

 

이 문제는 그대로 적용해보고 왜 그런 결과가 나왔는지 설명하면 되는 문제였는데 보면 어떤 것들을 적용하는지 알겠는데 막상 이걸 말로 설명하라고 하면 모르겠는거다.. 그게 모르는거겠지..? this가 상위환경을 참조한다. 여기까지면 좋은데 Javascript는 상황마다 달라서 오늘 설명을 듣고도 모르겠어서 하루종일 this 바인딩을 찾아보았다..

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);
Not Francis Ngannou VS John Jones
It is John Jones VS Ciryl Gane

 

자바스크립트의 경우 함수 호출 방식에 의해 this에 바인딩할 어떤 객체가 동적으로 결정된다. 다시 말해, 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.

 

첫번째의 경우, 암시적 바인딩으로 해당함수를 호출한 객체 즉, 콘텍스트 객체에 바인딩 되어 Francis Ngannou를 리턴하고 두번째의 경우도 같은 객체 내부에서 그 값을 바인딩해와서 John Jones를 리턴했다. 세번째의 경우 화살표함수는this를 바인딩하지 않는 함수로 전역객체를 가리키고 4번째 함수도 함수로서 독립적으로 호출했기에 전역 객체를 가리켰다.

그냥 같은 객체 내부에서그 값을 바인딩해오고 함수의 경우 또 그 안에 값을 가져오고 화살표함수는 this를 바인딩하지 않는 함수다.

var fullname = 'Ciryl Gane'

var fighter = {
    fullname: 'John Jones',
    opponent: {
        fullname: 'Francis Ngannou',
        getFullname: function () {
            return this.fullname; // 1. 암시적 바인딩(해당함수를 호출한 객체 즉, 콘텍스트 객체에 바인딩), Francis Ngannou
        }
    },

    getName: function() {
        return this.fullname; // 2. 암시적 바인딩(해당함수를 호출한 객체 즉, 콘텍스트 객체에 바인딩), John Jones
    },

    getFirstName: () => {
        return this.fullname.split(' ')[0]; // 3. 함수 바인딩(전역변수 참조) , Ciryl Gane 에서 공백을 기준으로 잘라서 인덱스 0번째인 Ciryl 값 리턴
    },

    getLastName: (function() {
        return this.fullname.split(' ')[1]; // 4. 함수 바인딩(전역변수 참조), Ciryl Gane 에서 공백을 기준으로 잘라서 인덱스 1번째인 Gane 값 리턴
    })()

}

console.log('Not', fighter.opponent.getFullname(), 'VS', fighter.getName()); // Not Francis Ngannou VS John Jones
console.log('It is', fighter.getName(), 'VS', fighter.getFirstName(), fighter.getLastName); // It is John Jones VS Ciryl Gane

 

함수로서 독립적으로 호출할때는 this는 항상 전역객체를 가리킨다

근데 사실 4번째는 아직도 아리까리한부분이 있긴해서 다시 공부해서 다시 봐야할 것 같다..

 

자바스크립트의 this keyword는 Java와 같은 익숙한 언어의 개념과 달라 혼란을 준다고 했는데 매번 자바만 보다가 자바스크립트를 배우니까 화살표 함수도 익숙하지 않고 이런 this 바인딩도 익숙하지 않은 것 같다

 

Java에서의 this는 인스턴스 자신(self)을 가리키는 참조변수이다. this가 객체 자신에 대한 참조 값을 가지고 있다는 뜻이다. 주로 매개변수와 객체 자신이 가지고 있는 멤버변수명이 같을 경우 이를 구분하기 위해서 사용된다. 아래 Java 코드의 생성자 함수 내의 this.name은 멤버변수를 의미하며 name은 생성자 함수가 전달받은 매개변수를 의미한다.

 

하지만 자바스크립트의 경우 Java와 같이 this에 바인딩되는 객체는 한가지가 아니라 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.

// JAVA
public Class Person {

  private String name;

  public Person(String name) {
    this.name = name;
  }
}

 

반응형