TIL archiving ···.ᐟ/JavaScript + TypeScript

[노트내용정리] this & 콜 어플라이 바인드 (Call, Apply, Bind)

dayoung-archive 2024. 8. 31. 23:24

📌 this

this는 객체를 가리키는 참조 변수. 호출되는 위치에 따라 다르게 this를 정의한다.

function a(){ console.log(this) }
a();               // window


let myObj = {
    val1: 100,
    func1: function () {
        console.log(this);
    }
}

myObj.func1();    // myObj
  • 전역 컨텍스트: this는 전역 객체(브라우저에서는 window)를 가리킨다.

 

함수의 'this'는 호출시점에 따라 달라진다. 

일반함수호출 위치에 따라 this를 정의하고, 화살표함수는 자신이 선언된 함수 범위에서 this를 정의한다.

const hello = {
  name: '이름ㅇㅇㅇ',
  normal: function () {
    console.log(this.name)
  },
  arrow: () => {
    console.log(this.name) 
  }
}
hello.normal()  // 이름ㅇㅇㅇ
hello.arrow()   // undefined
  • 일반함수(normal)은 호출된 위치에서 앞에 있는 객체 데이터인 hello가 곧 this이고, 거기서 name이라는 속성을 찾기 때문에 name의 값인 이름ㅇㅇㅇ이 출력된다.
  • 화살표함수(arrow)는 자신이 선언된 함수범위에서 this를 정의하는데 현재 코드에서는 this를 정확히 알 수 없다. 알 수 없는 부분에서 name의 속성을 찾기 때문에 undefined를 출력한다.

 

const timer = {
    name: '123!!',
    timeout: function () {
    setTimeout(function () { 
   }, 2000)
  }
 }
timer.timeout();   //undefined

➜ 일반함수는 호출되는 곳에서 this가 정의되고, 여기서는 setTimeout함수 내부로 콜백이 들어가서 어디선가 호출되기 때문에 출력 불가능.

 

const timer = {
  name: '123!!',
  timeout: function () {
    setTimeout(() => {      
      console.log(this.name)
    }, 2000)
  }
}
timer.timeout()    // 123!!

➜  setTimeout 함수를 화살표함수로 수정해주면 선언된 함수범위에서 this가 정의되므로 123!! 출력가능.

 

this 참고: https://ko.javascript.info/object-methods

 

 

📌 call, apply, bind

this가 가리키는 값이 달라지기 때문에 이것을 call, apply, bind를 사용해 this를 명시적으로 바인딩 해준다. (this가 무엇인지 정확하게 명시해주는 것)

 

1. call 

this를 특정 객체로 지정해줄 수 있다.

const ageNumber = {
  age: 999
}

function findAge() {
  console.log(this.age)
}

findAge.call(ageNumber)

➜  호출함수.call(this로 지정할 대상)

const ageNumber = {
  age: 999
}

function findAge() {
  console.log(this.age, name, location)
}

findAge.call(ageNumber, "John", "NY")
function add1(num1) {
    console.log('num1',num1);
    console.log('this',this);
    return num1  + this;
}

add1.call(10,5)   // this: 10,  add1: 5

 

➜ call()의 첫 번째 인수: this로 지정할 대상 / 두번째 인수부터는 함수에 넘겨 줄 값

 

 

2. apply

call처럼 this를 특정 객체로 지정해줄 수 있지만 배열형태로 인수로 넣어줘야 한다.

function add2(num1, num2, num3) {
    console.log('num1',num1);
    console.log('num2',num2);
    console.log('num3',num3);    
    console.log('this',this);

    return num1 + num2 + num3 + this;

}
add2.apply(10, [1,2,3])    // num1 1, num2 2, num3 3, this 10, 16(return값)

 

 

3. bind

call, apply처럼 this를 지정할 수 있지만 함수가 호출되지는 않는다. this를 명시적으로 함수를 반환한다.

할당할 변수 = 함수.bind(this로 지정할 대상, 함수에 넘겨줄 값)

할당할 변수를 호출.

function add1(num1) {
    console.log('num1',num1);
    console.log('this',this);
    return num1  + this;
}

const newFn = add1.bind(10, 10)
newFn();



function add(num) {
 return num + this;
}

const add5 = (num) => add.bind(5,num)

add5(10)  //15

 

call, apply : this를 명시적으로 함수 호출

bind : this를 명시적으로 함수 반환

 


call 참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call

apply 참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call

bind 참고: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind