9. this와 친해지기 (this 바인딩)/9.2 this 제어 방법

9.2.1 call로 this 바꾸기 - 도구를 빌려 쓰는 방법

thejavascript4kids 2025. 7. 12. 05:03

📘 9.2.1 call로 this 바꾸기 - 도구를 빌려 쓰는 방법

여러분에게 인사드려요. 지금까지 우리는 this라는 것이 마치 계절의 변화처럼 상황에 따라 스스로 모습을 바꾸는 것을 지켜보았죠. 넓은 세상에서는 window를, 어떤 작은 집 안에서는 그 집을, 새로운 생명이 태어날 때는 그 새로운 존재를 가리키며 말이에요.

그런데 여러분, 만약 우리가 직접 this가 누구를 바라볼지 정할 수 있다면 어떨까요? 마치 우리가 스스로 계절을 선택할 수 있는 것처럼요. 그런 놀라운 힘을 가진 것이 바로 call이라는 이름의 친구랍니다.

🧠 새로운 단어들과 친해지기

this를 우리 마음대로 움직일 수 있는 새로운 방법을 배우기 전에, 먼저 필요한 말들을 차근차근 이해해보아요.

단어 부드러운 설명
call 기능 어떤 일을 시킬 때 동시에 this가 누구를 가리킬지 우리가 직접 정해줄 수 있는 따뜻한 방법이에요.
this 연결하기 this가 특정한 누군가를 바라보도록 마음의 실을 연결해주는 것 같아요.
기능 빌려쓰기 다른 누군가가 가진 소중한 능력을 내 것처럼 잠시 사용할 수 있게 해주는 것이에요.

call이라는 영어 단어는 "부르다"라는 뜻을 가지고 있어요. 하지만 자바스크립트에서는 단순히 무언가를 부르는 것이 아니라, "이 일을 해주는데, this는 내가 정한 이 아이로 해줘"라고 부드럽게 부탁하는 것 같아요.

call이 무엇인지 천천히 알아보기

call은 자바스크립트가 우리에게 선물한 정말 소중한 능력 중 하나예요. 평소에는 자바스크립트가 스스로 결정하던 this를, 이제는 우리가 마음을 담아 직접 선택할 수 있게 해주거든요. 마치 친구의 물건을 잠시 빌려서 사용하는 것처럼 자연스럽게요.

이 능력의 가장 아름다운 점은 나눔의 기쁨을 느낄 수 있다는 것이에요. 어떤 이가 가진 멋진 능력을 다른 이들도 함께 사용할 수 있게 되니까요. 친구가 가진 예쁜 연필을 잠시 빌려서 그림을 그리는 것처럼 말이에요.

또한 call을 사용하면 같은 능력을 여러 곳에서 다시 사용할 수 있어서 비슷한 것을 여러 번 만들 필요가 없어져요. 한 번 만든 좋은 능력을 다양한 상황에서 계속 활용할 수 있는 것이죠.

따뜻한 이야기: 마을의 도구 나눔터

call을 더 가깝게 느낄 수 있도록 '마을의 도구 나눔터' 이야기를 들려드릴게요.

어떤 작은 마을에 도구를 나누어 쓰는 곳이 하나 있었어요. 그곳에는 "이름표"라는 특별한 도구가 하나 있었어요. 이 이름표에는 "안녕하세요! 제 이름은 ○○○입니다"라고 적혀있었어요. 이 이름표는 하나뿐이었지만, 마을의 여러 사람들이 이 이름표를 사용할 수 있었어요.

평소에는 각 사람이 자기 차례에 이름표를 가져가서 자신을 소개했어요. 철수가 가져가면 "안녕하세요! 제 이름은 철수입니다"라고 하고, 영희가 가져가면 "안녕하세요! 제 이름은 영희입니다"라고 했죠.

그런데 마을 어르신에게는 특별한 능력이 있었어요. "이 이름표를 철수가 사용하렴", "이 이름표를 영희가 사용하렴"이라고 직접 정해줄 수 있는 것이었어요. 이때 사용하는 그 특별한 능력이 바로 call이었어요.

더 따뜻한 점은 한 사람만 가지고 있던 특별한 이름표를 다른 사람에게도 나누어줄 수 있다는 것이었어요. 예를 들어 철수만 "저는 축구를 좋아해요" 이름표를 가지고 있었는데, 어르신이 "이 이름표를 영희가 사용하렴"이라고 하면 영희도 그 이름표를 사용할 수 있게 되는 거예요.

🎯 왜 call을 사용하는지 생각해보기

call이라는 능력을 사용하는 이유는 여러 가지가 있어요.

첫 번째로, 능력을 함께 나누는 기쁨을 느낄 수 있어요. 한 이가 가진 멋진 능력을 다른 이들도 사용할 수 있게 되어서, 비슷한 능력을 여러 번 만들 필요가 없어져요.

두 번째로, 같은 것을 반복해서 만드는 수고로움을 덜 수 있어요. 잘 만든 능력 하나를 다양한 곳에서 활용할 수 있어서, 우리의 코딩 여행이 더 쉽고 즐거워져요.

세 번째로, 더 유연한 마음으로 프로그램을 만들 수 있어요. 상황에 따라 같은 능력을 다른 곳에서 실행할 수 있어서, 더 다양하고 창의적인 해결책을 만들어낼 수 있어요.

마지막으로, 서로 협력하는 아름다움을 경험할 수 있어요. 서로 다른 것들이 능력을 함께 나누면서 더 복잡하고 흥미로운 일들을 만들어낼 수 있거든요.

⚙️ 기본 사용법을 차근차근 배우기

call의 사용법은 생각보다 어렵지 않아요. 하나씩 천천히 알아볼게요.

// 기본 사용법
기능이름.call(this로_사용할_객체);

// 추가 정보가 필요한 경우
기능이름.call(this로_사용할_객체, 정보1, 정보2);

// 객체의 기능을 다른 객체에서 사용
객체1.기능이름.call(객체2);

소중한 점들:

  • call첫 번째 정보는 항상 "this로 사용할 객체"예요.
  • 두 번째 정보부터는 원래 기능에 필요한 정보들이에요.
  • call을 사용하면 기능 안의 this가 첫 번째로 전달한 객체로 바뀌어요.

🧪 직접 해보면서 천천히 배우기

이제 실제 예시를 통해서 call이 어떻게 움직이는지 차근차근 알아보겠어요.

🔹 Ex1) 같은 인사를 다른 친구들이 해보기

첫 번째 예시에서는 call을 사용해서 같은 기능을 다른 객체의 this로 실행해보겠어요.

// 자기소개를 하는 기능 (아직 주인이 정해지지 않은 상태)
function introduce() {
    console.log("안녕하세요! 저는 " + this.name + "이고, " + this.age + "살입니다.");
}

// 두 명의 친구
let friend1 = {
    name: "철수",  // 이름은 철수예요
    age: 10        // 나이는 10살이에요
};

let friend2 = {
    name: "영희",  // 이름은 영희예요
    age: 11        // 나이는 11살이에요
};

// call로 this를 바꿔가며 기능 실행
console.log("=== call 기능 시작! ===");
introduce.call(friend1);  // call로 this를 friend1으로 바꿔요 -> "안녕하세요! 저는 철수이고, 10살입니다."
introduce.call(friend2);  // call로 this를 friend2로 바꿔요 -> "안녕하세요! 저는 영희이고, 11살입니다."

// 같은 기능이지만 this가 다르니까 다른 결과가 나와요!
console.log("=== 성공! ===");

이 코드를 보면, 먼저 introduce라는 혼자 있는 기능을 만들어요. 이 기능은 아직 어떤 객체에도 속하지 않은 상태예요. 그다음 두 개의 친구 객체를 만들고, call을 사용해서 같은 기능을 각각 다른 객체의 this로 실행해요. 마치 같은 대사를 다른 사람이 말하는 것처럼 따뜻하게요.

🔹 Ex2) 친구의 멋진 기능을 빌려서 사용하기

두 번째 예시에서는 한 객체의 기능을 다른 객체가 빌려서 사용하는 방법을 보여드릴게요.

// 강아지 객체 (울음소리 기능 있음)
let dog = {
    name: "멍멍이",  // 이름은 멍멍이예요
    sound: "멍멍",   // 울음소리는 멍멍이에요
    bark: function() {  // 울음소리를 내는 특별한 기능이에요
        console.log(this.name + "가 " + this.sound + " 소리를 내요!");
    }
};

// 고양이 객체 (울음소리 기능 없음)
let cat = {
    name: "야옹이",  // 이름은 야옹이예요
    sound: "야옹"    // 울음소리는 야옹이에요
};

// 새 객체 (울음소리 기능 없음)
let bird = {
    name: "짹짹이",  // 이름은 짹짹이예요
    sound: "짹짹"    // 울음소리는 짹짹이에요
};

console.log("=== 일반적인 강아지 울음소리 ===");
dog.bark();  // 강아지가 자신의 기능으로 소리를 내요 -> "멍멍이가 멍멍 소리를 내요!"

console.log("\n=== 기능 빌려쓰기! ===");
// 강아지의 bark 기능을 고양이와 새가 빌려서 사용
dog.bark.call(cat);   // call로 강아지 기능을 고양이가 사용 -> "야옹이가 야옹 소리를 내요!"
dog.bark.call(bird);  // call로 강아지 기능을 새가 사용 -> "짹짹이가 짹짹 소리를 내요!"

console.log("=== 모든 동물이 같은 방식으로 울 수 있어요! ===");

이 예시에서 아름다운 점은 catbird 객체에는 bark 기능이 없는데도, dog의 기능을 빌려서 마치 자신의 기능인 것처럼 사용할 수 있다는 것이에요. call의 도움으로 this가 각각의 객체를 가리키게 되어서 각자의 정보가 올바르게 나타나는 거예요.

🔹 Ex3) 추가 정보와 함께하는 call 기능

세 번째 예시에서는 추가 정보가 필요한 기능을 call로 사용하는 방법을 알아보겠어요.

// 취미 소개 기능 (추가 정보 2개 필요)
function introduceHobby(hobby1, hobby2) {
    console.log("안녕하세요! 저는 " + this.name + "입니다.");
    console.log("제 취미는 " + hobby1 + "와 " + hobby2 + "입니다!");
}

// 여러 친구들
let student1 = { name: "민수" };  // 민수라는 친구
let student2 = { name: "지혜" };  // 지혜라는 친구
let student3 = { name: "태양" };  // 태양이라는 친구

console.log("=== 친구들의 취미 소개 시간 ===");

// call로 this 지정하고 추가 정보도 함께 전달
introduceHobby.call(student1, "축구", "게임");      // 민수의 취미는 축구와 게임
// "안녕하세요! 저는 민수입니다." "제 취미는 축구와 게임입니다!"

introduceHobby.call(student2, "독서", "그림그리기");  // 지혜의 취미는 독서와 그림그리기
// "안녕하세요! 저는 지혜입니다." "제 취미는 독서와 그림그리기입니다!"

introduceHobby.call(student3, "노래", "춤");        // 태양의 취미는 노래와 춤
// "안녕하세요! 저는 태양입니다." "제 취미는 노래와 춤입니다!"

console.log("=== 모두 다른 취미를 가졌네요! ===");

이 예시에서는 call의 완전한 활용법을 보여줘요. 첫 번째 정보로 this를 지정하고, 두 번째와 세 번째 정보로는 원래 기능이 필요로 하는 정보들을 전달해요. 이렇게 하면 같은 기능으로 서로 다른 객체와 서로 다른 정보를 사용할 수 있어요.

🔄 call 사용하는 순서 차근차근 정리하기

지금까지 배운 call 사용 과정을 하나씩 천천히 정리해볼게요.

첫 번째 단계기능과 객체 준비예요. 사용할 기능과 this로 지정할 객체들을 마음을 담아 미리 준비해둬요.

두 번째 단계call 기능 사용 단계예요. 기능이름.call() 형태로 call 기능을 부드럽게 사용해요.

세 번째 단계this 객체 지정 단계예요. call의 첫 번째 정보로 this가 될 객체를 따뜻하게 전달해요.

네 번째 단계추가 정보 전달 단계예요. 원래 기능이 추가 정보를 필요로 한다면, 두 번째 정보부터 차례대로 전달해요.

마지막으로 가장 소중한 것결과 확인 단계예요. 기능이 지정된 객체의 this로 실행되어서 우리가 원하는 결과가 나오는지 확인해요.

🧚‍♀️ 따뜻한 이야기로 다시 배우기: 마을 도서관의 책 나눔 이야기

지금까지 배운 내용을 따뜻한 이야기로 다시 정리해볼게요.

옛날에 마을 도서관이라는 곳이 있었어요. 이 도서관에는 정말 특별한 시스템이 있었어요. 각 책(기능)을 읽는 사람에 따라 내용이 달라지는 것이었어요.

예를 들어 "자기소개 책"이라는 특별한 책이 있었는데, 이 책에는 "안녕하세요! 저는 ○○○입니다"라고 적혀있었어요. 철수가 이 책을 읽으면 "안녕하세요! 저는 철수입니다"라고 나타났고, 영희가 읽으면 "안녕하세요! 저는 영희입니다"라고 나타났죠.

그런데 도서관 사서에게는 call이라는 특별한 능력이 있었어요. 이 능력을 사용하면 "이 책을 철수에게 읽어주렴", "이 책을 영희에게 읽어주렴"이라고 부드럽게 부탁할 수 있었어요. 심지어 철수만 가지고 있던 "축구 이야기 책"을 영희에게 읽어주는 것도 가능했어요.

이런 따뜻한 시스템 덕분에 도서관의 책들은 정말 효율적으로 사용될 수 있었어요. 한 권의 책으로 수많은 사람들이 각자에게 맞는 내용을 읽을 수 있었고, 서로의 책을 나누어줄 수도 있었거든요.

🧠 자주 하는 실수와 조심할 점

call을 사용할 때 자주 하는 실수들을 미리 알아두면 더 안전하게 코딩할 수 있어요.

❌ 실수 1: call의 첫 번째 정보 빼먹기

function greet() {
    console.log("안녕하세요! " + this.name);
}

let person = { name: "철수" };

// 잘못된 사용
greet.call(); // this가 정해지지 않아요!

// 올바른 사용  
greet.call(person); // "안녕하세요! 철수"

이런 실수가 생기는 이유는 call의 첫 번째 정보가 this가 될 객체를 결정하는 핵심 요소이기 때문이에요. 이 정보가 없으면 call의 의미가 사라져버려요.

❌ 실수 2: call과 일반 기능 실행 헷갈리기

function introduce() {
    console.log("저는 " + this.name + "입니다.");
}

let person = { name: "영희" };

// 잘못된 방법 (person이 정보로 전달됨)
introduce(person); // "저는 undefined입니다."

// 올바른 방법 (person이 this가 됨)
introduce.call(person); // "저는 영희입니다."

이 혼동이 생기는 이유는 call과 일반 기능 실행의 목적이 완전히 다르기 때문이에요. 일반 기능 실행은 정보를 기능에 전달하는 것이고, call은 기능이 실행될 때의 상황(this)을 바꾸는 것이에요.

❌ 실수 3: 화살표 함수에 call 사용하기

let arrowFunc = () => {
    console.log("이름: " + this.name);
};

let person = { name: "민수" };

arrowFunc.call(person); // this가 바뀌지 않아요!

이 문제가 생기는 이유는 화살표 방식의 기능(=>)이 자신만의 this를 가지지 않고, 만들어진 순간의 상위 공간 this를 그대로 사용하기 때문이에요. 그래서 callthis를 바꾸려고 해도 무시되어 버려요.

✏️ 직접 해보기 - 따뜻한 연습 문제들

이제 배운 내용을 연습 문제를 통해서 차근차근 익혀볼게요.

마음을 가다듬고 코드와 함께 대화하듯 연습해보세요. 각 문제는 여러분이 call의 마음을 이해할 수 있도록 도와줄 거예요.

Ex1) 같은 기능으로 다른 친구들의 정보를 보여주기

// 정보를 화면에 보여주는 기능
function showInfo() {
    console.log("이름: " + this.name + ", 좋아하는 색: " + this.color);
}

// 다양한 사람 객체들
let person1 = { name: "수진", color: "빨간색" };  // 수진이는 빨간색을 좋아해요
let person2 = { name: "현준", color: "파란색" };  // 현준이는 파란색을 좋아해요
let person3 = { name: "서연", color: "초록색" };  // 서연이는 초록색을 좋아해요

// call로 각각 다른 객체의 정보 출력
showInfo.call(person1); // call로 this를 person1으로 바꿔요 -> "이름: 수진, 좋아하는 색: 빨간색"
showInfo.call(person2); // call로 this를 person2로 바꿔요 -> "이름: 현준, 좋아하는 색: 파란색"
showInfo.call(person3); // call로 this를 person3으로 바꿔요 -> "이름: 서연, 좋아하는 색: 초록색"

이 연습을 통해서 call의 기본적인 사용법과 this 변경 원리를 차근차근 익힐 수 있어요.

Ex2) 한 객체의 기능을 다른 객체에서 빌려서 사용해보기

// 선생님 객체 (수업 기능 있음)
let teacher = {
    name: "김선생님",     // 이름은 김선생님이에요
    subject: "수학",      // 과목은 수학이에요
    teach: function() {   // 수업하는 특별한 기능이에요
        console.log(this.name + "이 " + this.subject + " 수업을 합니다.");
    }
};

// 학생 객체들 (수업 기능 없음)
let student1 = { name: "지민", subject: "과학" };  // 지민이는 과학을 좋아해요
let student2 = { name: "은우", subject: "영어" };  // 은우는 영어를 좋아해요

// 학생들이 선생님의 teach 기능을 빌려서 사용
console.log("=== 학생들의 발표 시간 ===");
teacher.teach.call(student1); // 선생님 기능을 지민이가 빌려써요 -> "지민이 과학 수업을 합니다."
teacher.teach.call(student2); // 선생님 기능을 은우가 빌려써요 -> "은우이 영어 수업을 합니다."

이 문제는 기능 빌려쓰기의 실용적인 활용법을 이해하는 데 도움이 돼요.

Ex3) 추가 정보가 있는 기능을 call로 사용해보기

// 점수 발표 기능 (추가 정보 2개 필요)
function announceScore(subject, score) {
    console.log(this.name + "의 " + subject + " 점수는 " + score + "점입니다!");
    // 점수에 따라 격려의 말을 해줘요
    if (score >= 90) {
        console.log("훌륭해요!");
    } else if (score >= 80) {
        console.log("잘했어요!");
    } else {
        console.log("더 열심히 해봐요!");
    }
}

// 학생들
let student1 = { name: "하은" };  // 하은이라는 학생
let student2 = { name: "도윤" };  // 도윤이라는 학생

// call로 this 지정하고 추가 정보도 전달
announceScore.call(student1, "수학", 95);  // 하은이의 수학 점수 95점 발표
announceScore.call(student2, "과학", 85);  // 도윤이의 과학 점수 85점 발표

이 연습문제를 통해 call에서 추가 정보를 함께 전달하는 방법을 익힐 수 있어요.

🎮 보너스 문제 - 조금 더 깊이 있는 call 활용법

조금 더 도전해보고 싶은 분들을 위한 보너스 문제예요. 천천히 생각해보세요.

보너스 Q1. 다음 코드의 결과를 예상해보세요

function showMessage() {
    console.log("메시지: " + this.message + ", 보낸이: " + this.sender);
}

let email = { message: "안녕하세요!", sender: "철수" };
let letter = { message: "잘 지내세요~", sender: "영희" };

showMessage.call(email);
showMessage.call(letter);

정답:

  • "메시지: 안녕하세요!, 보낸이: 철수"
  • "메시지: 잘 지내세요~, 보낸이: 영희"

부드러운 설명: call을 사용해서 같은 기능을 서로 다른 객체의 this로 실행했기 때문에, 각각의 객체가 가진 messagesender 정보가 출력돼요.

보너스 Q2. 다음 중 올바른 call 사용법은?

function greet(greeting) {
    console.log(greeting + "! 저는 " + this.name + "입니다.");
}

let person = { name: "민지" };

// A번
greet.call(person, "안녕하세요");

// B번  
greet.call("안녕하세요", person);

정답: A번이 올바른 사용법이에요.

부드러운 설명: call의 첫 번째 정보는 항상 this가 될 객체이어야 해요. 두 번째 정보부터는 원래 기능에 필요한 정보들을 순서대로 전달하는 거죠.

📚 이전 단원 복습하기

9단원을 배우는 여러분을 위해 이전에 배운 내용을 차근차근 복습해볼게요.

복습 문제 1 - 8단원: 객체 메서드 만들기

// 8단원에서 배운 객체와 메서드를 사용해보세요
let calculator = {
    number: 0,
    add: function(value) {
        this.number += value;
        console.log("현재 숫자: " + this.number);
    },
    multiply: function(value) {
        this.number *= value;
        console.log("현재 숫자: " + this.number);
    }
};

calculator.add(5);        // "현재 숫자: 5"
calculator.multiply(3);   // "현재 숫자: 15"

복습 포인트: 객체의 메서드에서 this는 그 객체 자신을 가리켜요. 이 개념이 call을 이해하는 기초가 돼요.

복습 문제 2 - 5단원: 함수 만들기

// 5단원에서 배운 함수를 만들어보세요
function calculateArea(width, height) {
    let area = width * height;
    console.log("가로 " + width + "cm, 세로 " + height + "cm인 직사각형의 넓이는 " + area + "cm²입니다.");
    return area;
}

calculateArea(4, 6);  // "가로 4cm, 세로 6cm인 직사각형의 넓이는 24cm²입니다."
calculateArea(3, 8);  // "가로 3cm, 세로 8cm인 직사각형의 넓이는 24cm²입니다."

복습 포인트: 함수는 입력값을 받아서 일을 처리하고 결과를 돌려주는 도구예요. call은 이런 함수를 다른 상황에서 사용할 수 있게 해줘요.

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요.

학습 내용 이해했나요?
call의 기본 개념
기본 사용법과 문법
기능 빌려쓰기 방법
자주 하는 실수들
실전 예제 이해

🎯 추가 연습 문제들

조금 더 연습하고 싶은 분들을 위한 추가 문제들이에요.

추가 문제 1. call을 사용해서 다른 객체의 name을 출력하는 함수를 만들어보세요.

// 답:
function showName() {
    console.log("이름: " + this.name);
}

let person1 = { name: "수지" };
let person2 = { name: "태형" };

showName.call(person1); // "이름: 수지"
showName.call(person2); // "이름: 태형"

추가 문제 2. 다른 객체의 메서드를 call로 빌려서 사용해보세요.

// 답:
let cat = {
    name: "나비",
    speak: function() {
        console.log(this.name + "가 야옹 소리를 내요.");
    }
};

let dog = { name: "멍멍이" };

cat.speak.call(dog); // "멍멍이가 야옹 소리를 내요."

추가 문제 3. call로 매개변수가 있는 함수를 사용해보세요.

// 답:
function introduce(age) {
    console.log("저는 " + this.name + "이고 " + age + "살입니다.");
}

let person = { name: "하늘" };
introduce.call(person, 9); // "저는 하늘이고 9살입니다."

지금까지 call이라는 특별한 능력에 대해 자세히 알아보았어요. call을 사용하면 this를 자유자재로 움직일 수 있어서, 같은 기능을 다양한 상황에서 다시 사용할 수 있어요. 이는 코딩을 더 효율적이고 유연하게 만들어주는 정말 소중한 능력이에요.

📂 마무리 정보

오늘 배운 9.2.1 내용이 여러분의 자바스크립트 지식에 잘 자리 잡았나요? 다음 시간에는 더 재미있는 내용으로 만나요.

기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작