home강의 홈으로
Section 12. 스코프와 바인딩
Lesson 2. this의 동적 바인딩

👉 MDN 문서 보기



I. ⭐️ this - "이곳의~"

  • 기본적으로 자신이 속한 곳을 가리킴 - 문맥 context
  • 💡 함수의 호출 방식에 따라 가리키는 바가 달라짐 - 자바스크립트 특성


1. 전역에서의 this

console.log(this);

💡 아래의 환경들에서 각각 실행해 볼 것

  • 브라우저의 콘솔창: Window 객체 - globalThis와 같음
  • Node.js의 REPL: global 객체 - globalThis와 같음
  • .js문서로 작성 후 실행 - 빈 객체

    • Node.js에서 각 .js 문서들은 이후 배울 모듈로서 실행되기 때문


2. 함수 안에서의 this

느슨한 모드와 엄격 모드에서 다르게 동작

function func () { console.log(this); // globalThis } func(); 'use strict'; function func () { console.log(this); // undefined } func();
  • 객체에 속하지 않은 함수에서는 this 사용이 의미 없음


3. 객체 안에서의 this

  • ⚠️ 일단 화살표 함수 제외

a. 객체 리터럴 - 해당 객체를 가리킴

const obj = { x: 123, getX: function () { return this.x; } } console.log(obj.getX());

b. 생성자 함수 - 생성될 인스턴스를 가리킴

function Person (name, age) { this.name = name; this.age = age; this.introduce = function () { return `저는 ${this.name}, ${this.age}세입니다.` } } console.log( new Person('홍길동', 20).introduce() );

c. 클래스 선언 - 생성될 인스턴스를 가리킴

class YalcoChicken { constructor (name, no) { this.name = name; this.no = no; } introduce () { return `안녕하세요, ${this.no}호 ${this.name}점입니다!`; } } console.log( new YalcoChicken('강남', 17).introduce() );



II. ⭐ 동적 바인딩

  • 자바스크립트의 독특한 동작방식
  • this가 가리키는 대상이 함수의 호출 주체 또는 그 방식에 따라 달라짐

const korean = { favorite: '김치', makeStew: function (isHot, pots) { return `${isHot ? '매운' : '순한'} ${this.favorite}찌개 ${pots}냄비`; } }; const italian = { favorite: '피자' }; console.log( korean.makeStew(true, 1) ); // 이탈리아인에게 한국인이 찌개 끓이는 법을 알려줌 italian.makeStew = korean.makeStew; console.log( italian.makeStew(false, 2) );
  • 💡 함수가 누가, 어떻게 호출되었는가에 따라 this가 가리키는 대상이 달라짐


해결방법들

1. call를 사용한 함수 호출

console.log( italian.makeStew.call(korean, false, 2) );

2. apply를 사용한 함수 호출

console.log( italian.makeStew.apply(korean, [false, 2]) );

3. ⭐ bind를 사용한 this 대상 고정

// ⭐ this가 바인딩된 새 함수를 만듦 italian.makeRightStew = korean.makeStew.bind(korean); console.log( italian.makeRightStew(false, 2) ); // 💡 추가 인자들까지 바인딩 가능 italian.makeClassicStew = korean.makeStew.bind(korean, true, 1); console.log( italian.makeClassicStew() );

4. 바인딩된 함수를 내보내는 함수

const korean = { favorite: '김치', makeStew: function (isHot, pots) { return `${isHot ? '매운' : '순한'} ${this.favorite}찌개 ${pots}냄비`; }, teachMakingStew: function () { return this.makeStew.bind(this); } }; const italian = { favorite: '피자' }; italian.makeStew = korean.teachMakingStew(); console.log( italian.makeStew(false, 2) );

5. 생성자 함수일 경우 - 함수 자체를 미리 인스턴스에 바인딩하기

function Korean () { this.favorite = '김치'; this.makeStew = function (isHot, pots) { return `${isHot ? '매운' : '순한'} ${this.favorite}찌개 ${pots}냄비`; }; // 💡 여기서 바인딩을 고정시켜버림 this.makeStew = this.makeStew.bind(this); } function Italian () { this.favorite = '피자'; } const korean = new Korean(); const italian = new Italian(); italian.makeStew = korean.makeStew; console.log( italian.makeStew(false, 2) );

call, apply, bind의 다른 활용

const korean = { favorite: '김치', makeStew: function (isHot, pots) { return `${isHot ? '매운' : '순한'} ${this.favorite}찌개 ${pots}냄비`; } }; console.log( // 💡 임의로 특수한 동작을 시킬 때 korean.makeStew.call({favorite: '된장'}, true, 2) );

// 객체들이 가져다 쓰도록 만든 함수 function intro (job) { return `${this.name}(${this.age}세) - ${job}` } const hong = { name: '홍길동', age: 20 }; const jeon = { name: '전우치', age: 25 }; // 동적 바인딩 특성 활용 hong.intro = intro; console.log( hong.intro('개발자') ); console.log(intro.call(hong, '개발자')); console.log(intro.apply(jeon, ['사무직'])); const introHong = intro.bind(hong, '개발자'); console.log( introHong() );



⭐ 배열 메서드의 thisArg

  • 해당 강 다시보기
  • 콜백으로 주어진 함수 내에서 this가 가리킬 대상
  • 보통 콜백함수 다음 인자로 넣음
function recommendForYou (me) { const products = [ { sex: 'F', size: 'M' }, { sex: 'M', size: 'L' }, { sex: 'F', size: 'M' }, { sex: 'U', size: 'S' }, { sex: 'M', size: 'L' }, { sex: 'F', size: 'S' }, ]; products .map((itm, idx) => { return { ...itm, idx } }) // ⚠️ 화살표 함수 대신 function 선언 함수 사용 주목 .filter(function ({sex, size}) { return ['U', this.sex].includes(sex) && size === this.size }, me) // 💡 thisArg .forEach(function ({idx}) { console.log(`${this.name}님, ${++idx}번은 어떠세요?`); }, me); // 💡 thisArg } const peter = { name: '피터', sex: 'M', size: 'L' }; const jane = { name: '제인', sex: 'F', size: 'S' }; recommendForYou(peter); recommendForYou(jane);

🤔얄코에게 질문하기질문은 반.드.시 이리로 보내주세요! ( 강의사이트 질문기능 ✖ )

강의에서 이해가 안 되거나 실습상 문제가 있는 부분,
설명이 잘못되었거나 미흡한 부분을 메일로 알려주세요!

답변드린 뒤 필요할 경우 본 페이지에
관련 내용을 추가/수정하도록 하겠습니다.

이메일 주소
yalco@yalco.kr
메일 제목 (반드시 아래 제목을 붙여넣어주세요!)
[질문] 제대로 파는 자바스크립트 (유료 파트) 12-2

🛑질문 전 필독!!

  • 구글링을 먼저 해 주세요. 들어오는 질문의 절반 이상은 구글에 검색해 보면 1분 이내로 답을 찾을 수 있는 내용들입니다.
  • 오류 메시지가 있을 경우 이를 구글에 복붙해서 검색해보면 대부분 짧은 시간 내 해결방법을 찾을 수 있습니다.
  • 강의 페이지에 추가사항 등 놓친 부분이 없는지 확인해주세요. 자주 들어오는 질문은 페이지에 추가사항으로 업데이트됩니다.
  • "유료파트의 강의페이지는 어디 있나요?" - 각 영상의 시작부분 검은 화면마다 해당 챕터의 강의페이지 링크가 있습니다.
  • 질문을 보내주실 때는 문제가 어떻게 발생했고 어떤 상황인지 등을 구체적으로 적어주세요. 스크린샷을 첨부해주시면 더욱 좋습니다.
🌏 Why not change the world?