this

HanHyuk·2023년 12월 2일

this란?

  • '이것'
  • Javascript의 예약어

this의 역할

  • 자신이 속한 객체나 인스턴스를 가리키는 자기 참조 변수
    - 자신이 속한 객체나 인스턴스의 프로퍼티나 메서드 참조 가능
  • 함수를 호출할 때, 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정됨
    - 즉, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 결정된다는 뜻

바인딩?

  • 식별자와 값을 연결하는 과정
  • this 바인딩은 this와 this가 가리킬 객체를 바인딩 하는 과정

호출

  • 기본적으로 this는 전역객체(Global object)에 바인딩됨
  • 일반 전역함수는 물론이고 내부함수의 경우도 this는 외부함수가 아닌 전역객체에 바인딩됨
  • 예시 코드 1
function a1Fn() {
	console.log("a1Fn is...", this); 
    function a2Fn() {
    	console.log("a2Fn is...", this);
    }
    a2Fn(); // a2 is... window
}
a1Fn(); // a1 is... window
  • 객체의 메서드로 호출될 때 this는 해당 객체를 가리킴
var apple = '독사과';
var home = {
  apple: '사과',
  eatApple: 'eatAppleFn
}

function eatAppleFn() {
  console.log(`백설공주가 ${this.apple}를 먹습니다.`);
}

// 객체 메서드 호출
home.eatApple(); // 백설공주가 사과를 먹습니다.

// 함수 직접 호출
eatAppleFn(); // 백설공주가 독사과를 먹습니다.
  • 객체 메서드로 호출 된 상황의 경우, home의 메서드로써 호출되었기 때문에 여기서 this는 home을 가리키기 때문에 보통 사과를 먹게 됨
  • 함수를 직접 호출하는 상황의 경우, eatAppleFn()은 어디에도 바인드 되어 있지 않기 때문에 this는 window를 뜻하고 위에 apple을 독사과로 정의해 두었기 때문에 독사과를 먹게 됨
  • 이와 같이 같은 eatAppleFn()을 호출했지만 어떤 방식으로 호출했느냐에 따라 this가 참조하는 객체가 달라짐
  • 예시 코드 2
var sejelye = '백설공주';

function mirrorReply() {
  console.log(`세상에서 제일 예쁜 사람은 ${this.sejelye}입니다.`); 
}

// 생성자 함수
function MagicMirror(name) {  
  this.sejelye = name;
  this.reply = mirrorReply;
}

// 새로운 거울 생성
var newMirror = new MagicMirror('왕비님');

newMirror.reply(); // 세상에서 제일 예쁜 사람은 왕비님입니다.
  • new 키워드로 MagicMirror의 인스턴스를 생성하였고 name에 해당하는 부분이 '왕비님' 이므로 여기서 newMirror 인스턴스의 mirrorReply 함수 내의 this는 '왕비님'이 됨

call, apply, bind를 이용한 호출

  • call, apply, bind를 이용하면 'this'를 원하는 객체에 연결할 수 있음
  • 내부함수를 사용하면서도 this가 원하는 객체를 가리키도록 연결해 줄 수 있음
var apple = '독사과';
var home = {
  apple: '사과',
  eatApple: function() {
    eatAppleFn();       
  },
  eatAppleCall: function() {
    // 여기서의 this는 home
    eatAppleFn.call(this); 
  },  
  eatAppleBind: function() {
    // 여기서의 this는 home
    (eatAppleFn.bind(this))(); 
  }
}

function eatAppleFn() {	
  console.log(`백설공주가 ${this.apple}를 먹습니다.`);    
}

home.eatApple();     // 백설공주가 독사과를 먹습니다.
home.eatAppleCall(); // 백설공주가 사과를 먹습니다.
home.eatAppleBind(); // 백설공주가 사과를 먹습니다.
  • eatAppleCall과 eatAppleBind 메서드의 this는 home
  • 이 this를 call 또는 bind의 인자로 제공하여 eatAppleFn 함수 내에서의 this로 사용할 수 있음.
  • call vs bind
    • 즉시 호출 vs 캐싱
      • call은 함수를 즉시 호출함
      • bind는 함수를 호출하지 않고 새로운 함수를 반환, 반환된 함수는 나중에 필요할 때 호출 가능
    • 매개변수 전달
      • call은 함수에 대한 매개변수를 순서대로 전달
      • bind는 함수에 대한 매개변수를 전달하지 않고 나중에 반환된 함수를 호출할 때 매개변수 전달
  • call vs bind 예시 코드
var obj = { value: 42 };

function getValue(prefix) {
  console.log(prefix + this.value);
}

// call 사용
getValue.call(obj, "The value is: "); // 출력: The value is: 42

// bind 사용
var boundFunction = getValue.bind(obj, "The value is: ");
boundFunction(); // 출력: The value is: 42
  • call은 함수를 즉시 호출하고, bind는 함수를 호출하지 않고 새로운 함수를 반환 후, 나중에 boundFunction이 호출될 때 원래 함수가 호출되면서 this 값과 매개변수가 전달
  • 즉, call은 즉시 함수를 호출하고 매개변수를 전달할 때 사용
  • bind는 새로운 함수를 생성하고 나중에 필요한 시점에 호출할 때 this 값을 설정하는 데 사용
profile
선한 영향력을 펼치는 개발자가 되겠습니다.

0개의 댓글