This

Chanhee Jang·2023년 3월 28일
0

JS

목록 보기
3/9

javascript의 this는 실행컨텍스트가 생성될 때 함께 결정된다.

실행 컨텍스트는 함수를 호출할 때 생성된다. 요컨대, this는 함수가 호출될 때 결정된다.


전역 공간에서의 this

전역 공간의 this는 전역 객체다. 전역 컨텍스트를 생성하는 주체가 전역 객체이기 때문이다.

브라우저의 전역 객체는 window이고, node.js 환경의 전역 객체는 global이다.


전역 변수를 선언하면 자바스크립트 엔진은 이를 전역 객체의 프로퍼티로 할당한다.

전역 변수를 선언하나 전역 객체(window, global)로 프로퍼리를 할당하나 똑같지만,

삭제 할 때의 동작은 다르다.

var a = 1;
delete window.a;
console.log(a, window.a, this.a); // 1, 1, 1 - 삭제 안됨

var b = 2;
delete b;
console.log(b, window.b, this.b); // 2, 2, 2 - 삭제 안됨

window.c = 3;
delete window.c;
console.log(c, window.c, this.c); // c is not defined - 삭제 됨

window.d = 4;
delete d;
console.log(d, window.d, this.d) // d is not defined - 삭제 됨

결과 정리

  1. var 로 선언해서 해당 변수를 삭제하는 경우
    1. 삭제 되지 않는다.
  2. window 전역 객체로 해당 프로퍼티를 삭제하는 경우
    1. 삭제 된다!

메소드로서 호출할 때, 메소드 내부의 this

JS에서의 함수와 메소드의 개념부터 알아보자

독립성이라는 차이가 있다.

함수는 그 자체로 독립적인 기능을 수행하는 반면, 메소드는 자신을 호출한 대상 객체에 관한 동작을 수행한다.

어떤 함수를 객체의 프로퍼티에 할당했을 때, 그 자체로 메소드가 되는 것이 아니다.

객체의 메소드로서 호출할 때만 메소드가 된다. 그렇지 않은 상황이면 함수이다.

var func = function (x) {
  console.log(this, x);
};

func(1); // Window { ... } 1

var obj = {
  method: func,
}

obj.method(2); // { method: func } 2

메소드 내부의 this

메소드 내부의 this호출한 주체에 대한 정보가 담긴다.

var func = function (x) {
  console.log(this, x);
};

var obj = {
  method: func,
  inner: {
    methodB: func
  }
}

obj.method(2); // { method: func } 2
obj.inner.methodB(3); // { methodB: func } 3

함수로서 호출할때, 함수 내부의 this

var obj1 = {
  outer: function () {
    console.log(this);

    var innerFunc = function () {
      console.log(this);
    }

    innerFunc(); // this: Window

    var obj2 = {
      innerMethod: innerFunc
    };

    obj2.innerMethod(); // this: { innerMethod: innerFunc } => obj2 객체
  }
}
obj1.outer(); // this: { outer: f, ... } => obj1 객체

this 바인딩은 함수를 실행하는 주변 환경이 중요하지 않음

오직 함수 호출인지, 메소드 호출인지가 중요한 거임


ES5에서의 this 우회하기

var obj = {
  outer: function () {
    console.log(this); // { outer: f } => obj 객체

    var innerFunc1 = function () {
      console.log(this);
    };

    innerFunc1(); // Window => 전역 객체

    var self = this;

    var innerFunc2 = function () {
      console.log(self); // { outer: f } => obj 객체
    };

    innerFunc2();
  }
};

obj.outer();

ES6에서의 함수 호출할 때, 함수 내부 this

ES6에서는 함수 내부의 this가 전역 객체를 바라보는 문제가 생겨, this를 바인딩하지 않는 화살표 함수를 도입함

화살표 함수는 실행 컨텍스트를 생성할 때, this 바인딩 과정이 빠져서 상위 스코프의 this를 활용할 수 있다.

var obj = {
  outer: function () {
    console.log(this); // { outer : f } => obj 객체

    var innerFunc = () => {
      console.log(this); // { outer : f } => obj 객체
    }

    innerFunc();
  }
};

obj.outer();

콜백 함수 내부의 this

자기 맘대로다.

forEach에 넣는 함수의 this는 전역 객체를 바라본다.

addEventListener의 this는 해당 셀렉터를 바라본다.


생성자 함수 내부의 this

var Cat = function (name, age) {
  this.bark = "야옹";
  this.name = name;
  this.age = age;
};

var choco = new Cat('초코', 7);
var nabi = new Cat('나비', 5);
console.log(choco, nabi); // 초코 객체, 나비 객체

명시적 this 바인딩

call 메소드

var func = function (a, b, c) {
  console.log(this, a, b, c);
};

func(1, 2, 3); // Window, 1, 2, 3
func.call({ x: 1 }, 4, 5, 6); // { x: 1 }, 4, 5, 6

임의의 객체를 this로 지정할 수 있다.

apply 메소드

var func = function (a, b, c) {
	console.log(this, a, b, c);
};

func.apply({ x : 1 }, [4, 5, 6]); // { x: 1 }, 4, 5, 6

call 과 같지만, apply 메소드는 실행시킬 함수의 인자를 배열로 전달한다는 점이 다르다.

bind 메소드

var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
}

var bindFunc = func.bind({ x : 1});
bindFunc(5, 6, 7, 8); // { x : 1}, 5, 6, 7, 8
var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
}

var bindFunc = func.bind({ x : 1}, 4, 5);
bindFunc(7, 8); // { x : 1}, 4, 5, 7, 8

console.log(bindFunc.name); // bound func

넘겨받은 this와 인수를 적용한 새로운 함수를 반환해주는 메소드

bind된 함수의 name을 살펴보면 bound 접두어가 붙는다.


번외

콜백함수에 this 인자를 명시적으로 줄 수 있는 함수들이 있다.

Array.prototype.forEach(callback[, thisArg]) 이 대표적이다.


요약

  1. 전역공간 this는 실행되는 곳의 전역 객체(window, global) 참조
  2. 객체의 메소드 호출은 (메소드 앞의) 해당 객체를 참조
  3. 함수 호출은 전역 객체 참조, 메소드 내부 함수도 똑같다.
  4. 화살표 함수는 실행 컨텍스트 생성할 때 this 바인딩이 빠지기 때문에 상위 컨텍스트의 this를 그대로 쓸 수 있음
  5. 생성자 함수의 this는 생성자 인스턴스를 참조
  6. call, apply 는 this를 명시적으로 지정하며 함수, 메소드를 호출한다.
  7. bind는 this, 함수에 넘길 인수를 일부 지정해서 새로운 함수를 만든다.
  8. 콜백 함수의 this는 일반적으로 전역 객체, 그러나 명시적으로 this 인자를 받을 수 있다.

Refer - Core Javascript

profile
What is to give light must endure burning

0개의 댓글