this와 call, apply, bind, arrow function

🌊·2022년 1월 13일
0

기술공부

목록 보기
2/4
post-thumbnail

this

  • 객체와 연관이 깊다.
  • 현재 실행 컨텍스트를 기반으로 호출자가 누구인지를 나타내는 식별자.

Context 객체

  • this가 바라보고 있는 어떤 객체

this 동작 방식

기본 바인딩 (전역 객체)

  • 기본적으로 this는 전역 객체(window)를 Context 객체로 갖는다.
  • 전역 스코프에서 정의한 변수들은 전역 객체에 등록된다.
let a = 10; // 전역 스코프에서 정의한 변수

console.log(this.a); // == window.a와 동일하다.

this.b = 10; // 의미적으로 let b = 10과 동일하다.

function f1() {
  return this;
}

// 크롬 개발자 도구
f1() === window; // true

// Node.js
f1() === global; // true

크롬 브라우저의 경우 this를 출력해보면 window 객체가 전역 객체로 나온다.

암시적 바인딩

  • 어떤 객체를 통해 함수가 호출된다면 그 객체가 바로 thisContext 객체가 된다.
let obj = {
  a: 20,
  func: function() {
    console.log(this.a);
  }
};

obj.func(); // 20

기본 바인딩 + 암시적 바인딩

let b = 100;

let obj = {
  a: 20,
  func: function() {
    console.log(this.b)   
  }
};

obj.func(); // undefined
let globalFunc = obj.func;
globalFunc() // 100

처음 obj.func()Context 객체가 obj이므로 obj에서 b 변수를 찾을 수 없다.
하지만 globalFunc는 전역스코프에서 정의한 변수이기 때문에 Context 객체가 window 객체이다. window 객체에서 b가 선언되었기 때문에 해당 값을 출력할 수 있다.

this는 어디서 호출 되었는지가 매우 중요하다.

let obj = {
  func: function() {
    return this;
  }
};

let obj2 = {
  method: obj.func
};

console.log( obj2.method() === obj2 ); // true
console.log( obj.fn() === obj ); // true

thisobj2.method로 부터 호출을 받았기 때문에 thisContext 객체는 obj2가 맞다.
obj.fn()obj.fn()로 부터 호출을 받았기 때문에 해당 thisContext 객체는 obj이다.

명시적 바인딩

  • 함수(함수 객체)는 call, apply, bind 메소드를 가지고 있는데, 첫 번째 인자로 넘겨주는 것이 this Context 객체가 된다.

call(), apply()

  • this의 값을 한 문맥에서 다른 문맥으로 넘기려면 사용한다.
  • 첫 번째 매개변수로 객체를 제공하면 this가 그 객체에 묶인다.
let obj = { txt: 'in Obj'};

let txt = 'global';

function func() {
  return this.txt;
}

func(); // global
func().call(obj); // in Obj
func().apply(obj); // in Obj

call()

function add(c, d) {
  return this.a + this.b + c + d;
}

let o = {a: 1, b: 3};

add.call(o, 5, 7); // 16

첫 번째 매개변수 뒤에 이어지는 인수들은 함수 호출에 사용할 매개변수이다.

apply()

function add(c, d) {
  return this.a + this.b + c + d;
}

let o = {a: 1, b: 3};

add.apply(o, [10, 20]);

callapply의 유일한 차이점은 apply는 인자를 배열로 만들어서 넣는다.

bind()

  • 메서드가 호출되면 새로운 함수를 생성한다.
  • 함수가 가리키는 this만 바꾸고 호출하지는 않는 것이다.
  • callapply와 비슷하지만 호출은 하지 않고 함수만 반환한다.
this.x = 9;
let obj = {
  x: 81,
  getX: function () {
    return this.x;
  },
};

obj.getX(); // 81
let globalfunc = obj.getX;

let bindFunc = globalfunc.bind(obj);
bindFunc(); // 81

bind 함수에서 obj와 바인딩 된 this가 있는 새로운 함수를 생성한다.
bindFunc에서 this.xobj와 바인딩 된 x를 가리킨다.
만약 obj2 객체에서 x40이고 bindFuncobj2를 바인딩한 새로운 함수를 생성하면 obj2x를 가리키게 된다.

화살표 함수에서 this

  • 화살표 함수에서 this는 자신을 감싼 정적 범위이다.
  • call(), bind(), apply()를 사용해 호출 할 때 this 값을 인수로 넘겨줘도 무시된다.
  • function 키워드는 해당 객체를 바인딩하여 this의 값을 변경하는 것
  • 화살표 함수는 상위 객체의 this를 그대로 이어 받아서 (스스로의 this 바인딩을 제공하지 않는다). 사용한다.
var obj = {
 i:10,
 b: () => console.log (this.i,this), //undefined, window
 c: function() {
  console.log(this.i, this) //10, obj
  }
} 

화살표 함수는 this를 가지지 않는 것은 아니다. 해당 객체보다 상위 객체의 this를 그대로 이어 받는다.
새롭게 해당 객체를 바인딩하지 않기 때문에 화살표 함수에서의 thisfunction 키워드의 this와 다르게 나타난다.

출처
https://velog.io/@nayeon/Javascript%EC%97%90%EC%84%9C%EC%9D%98-this-%EC%99%80-call-apply-bind-%EB%A9%94%EC%84%9C%EB%93%9C

0개의 댓글