2022.03.22 - [Studying/Development General] - [개발상식 찍먹] JavaScript - Call, Apply, 그리고 Bind (1)
2022.03.23 - [Studying/Development General] - [개발상식 찍먹] JavaScript - this 키워드
확인해 보시기 바랍니다 😉
JavaScript Function call(), apply() - advanced
지난 두 찍먹 포스트에서 우리는 어떻게 call 메소드를 사용하는지 코드 예제를 통해서 확인 해 보았습니다. 이번에는 call() 가 this 의 개념을 모두 사용하여 코드 예제를 작성해 보도록 하겠습니다.
const person = {
firstName: "John",
lastName: "Doe",
displayName: function() {
console.log(`${this.firstName} ${this.lastName}`); // 여기서 this 는 person 객체를 참조
}
};
const person1 = {
firstName: "Jane",
lastName: "Doe"
};
function displayName() {
console.log(`${this.firstName} ${this.lastName}`); // 함수 안에서 사용 된 this 는 전역 객체를 참조
}
// this.firstName = "Elon"; // line 18
// this.lastName = "Musk"; // line 19
person.displayName.call(person1);
displayName(); // "undefined undefined" if line 18 and 19 are commented out
첫번째 호출문 person.displayName.call(person1); 은 우리가 이미 확인했듯이 'Jane Doe' 가 출력 될 것입니다. 하지만, 두번째 displayName(); 은 어떻게 될까요? 기억하실 지 모르겠지만, 객체 안의 메소드 형태가 아닌 함수의 형태일 때, 그 함수 안의 this 는 전역 객체 (예를 들면 브라우저 window) 를 가리킨다고 지난 포스트에서 공부했습니다.
다시 위의 코드를 보면, person 객체 안에 정의 된 firstName 과 lastName 프로퍼티를 제외하면, 그 어디에서도 firstName 과 lastName 을 볼 수 없습니다. 따라서 결과값은 "undefined undefined" 가 될 것입니다. 하지만 만약 우리가 따로 this.firstName 과 this.lastName 을 선언 해 준다면, 그 의미는 window 전역 객체 안에 firstName 과 lastName 프로퍼티가 생성 된다는 의미이기에 독립 함수 안에서 this.firstName 과 this.lastName 의 값을 받아올 수 있게 됩니다.
또 다른 예제입니다. 이번에는 call() 메소드를 이용하여 독립 선언 되어있는 함수 displayName 에 인자 객체가 출력 되도록 해보겠습니다.
function displayName() {
console.log(`${this.firstName} ${this.lastName}`);
}
const person = {
firstName: "Bill",
lastName: "Gates"
};
displayName.call(person);
/** 출력값
// console.log(this);
{
firstName: "Bill",
lastName: "Gates"
}
// console.log(`${this.firstName} ${this.lastName}`);
"Bill Gates"
*/
위의 코드에서 call 메소드에 person 객체를 인자로 보냅니다. 그렇게 되면 this 는 전역 객체 대신 person 객체를 참조하게 됩니다. 이 예제 코드를 통해서 우리는 한 가지 결과를 도출할 수 있습니다.
call() 과 apply() 메소드에서 this 는 첫번째 인자를 참조한다. 인자 타입은 object, string, int 관계가 없다.
JavaScript Function bind() - advanced
지난번 찍먹편에서 우리는 bind() 를 한 객체에서 다른 객체의 메소드를 빌려올 때 사용한다는 것을 확인했습니다. 이번 포스트에서는 조금 더 자세하게 알아보도록 하겠습니다.
bind() 메소드는 this 를 보존하기 위해서도 사용이 되는데요....
이게 또 뭔 소린지 코드 예제를 통해 알아보겠습니다.
// Code from https://www.w3schools.com/js/js_function_bind.asp
const person = {
firstName:"John",
lastName: "Doe",
display: function () {
let x = document.getElementById("demo");
x.innerHTML = this.firstName + " " + this.lastName;
}
}
person.display();
너무 많이 봐서 이젠 나름 익숙해 진 코드입니다. 하지만 마지막으로 한번 더! 말씀 드리자면, person 객체 안의 this 는 person 객체를 참조합니다. 그럼 bind() 메소드가 this 를 보존하기 위해서 사용 된다는 말은 도대체 무엇이냐 하면:
const person = {
firstName:"John",
lastName: "Doe",
display: function () {
let x = document.getElementById("demo");
x.innerHTML = this.firstName + " " + this.lastName;
}
}
setTimeout(person.display, 3000);
위의 코드를 살펴보도록 하겠습니다. 위의 코드는 3초 후에 person 객체의 이름을 디스플레이 하라는 코드입니다. setTimeout 메소드는 첫번째 인자를 콜백 펑션으로 받는데, 위의 코드를 실행시키게 되면, person 객체의 이름 대신 undefined 가 출력됩니다. 그 이유는 함수가 콜백으로 사용될 경우에 this 가 보존 되지 않기 때문입니다.
그렇다면 this 를 보존하기 위해서 어떻게 해야 하냐? 예상 가능하시겠지만 바로 bind() 메소드를 사용하는 것입니다.
const display = person.display.bind(person);
setTimeout(display, 3000);
이처럼 bind 메소드를 사용하게 되면 this 가 보존 가능하고 3초 뒤에 person 객체의 이름이 출력 되는 것을 확인하실 수 있습니다.
이렇게 call, apply, bind, 그리고 this 에 대하여 야무지게 찍먹 + 부먹 해 보았습니다. 처음 예상했던 것보다 더 오랜 시간이 소요되었지만 그래도 이번 기회에 좀 더 자세히 공부할 수 있었다는 점에 대해 나름 성취감도 느끼고 있습니다. 최대한 쉽게 풀어서 써 보려고 했는데 어떻게 잘 됐는지 모르겠습니다. 혹시 이해가 가지 않는 부분이 있으신 분들은 댓글로 남겨주시면 제가 아는 선에서 최대한 자세하게 알려드리도록 노력해 보겠습니다. 그럼 오늘은 이만 쉬러... 얍!
'Studying > JavaScript & Frameworks' 카테고리의 다른 글
[자바스크립트 떠먹여 주는 남자] Function 과 Method 의 차이점 (0) | 2022.03.24 |
---|---|
[자바스크립트 떠먹여 주는 남자] this 키워드 (0) | 2022.03.23 |
[자바스크립트 떠먹여 주는 남자] Call, Apply, 그리고 Bind (1) (2) | 2022.03.22 |
[Node.js 떠먹여 주는 남자] Node.js 의 단점 (0) | 2022.03.20 |
[Node.js 떠먹여 주는 남자] Node.js 의 장점 (0) | 2022.03.20 |