TIL 79 | 코어 자바스크립트(2) this 1

meow·2020년 11월 30일
0

JavaScript

목록 보기
29/46

시대의 명작 코어 자바스크립트를 읽고 자바스크립트 마스터에 도전합니다... (this는 챕터 3이지만, 실행 컨텍스트가 어려워서 먼저 공부하기로!)

상황에 따라 달라지는 this

this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다. 즉 함수를 호출할 때 결정된다. 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라진다고 생각하면 된다.

전역 공간에서의 this

전역 공간에서의 this는 전역 객체를 가리킨다. 브라우저 환경에서 전역 객체는 window, Node.js 환경에서는 global 이다.

var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1

메서드로 호출할 때 그 내부에서의 this

함수 vs 메서드

함수와 메서드 둘 다 미리 정의한 동작을 수행하는 코드 뭉치이지만, 함수는 그 자체로 독립적인 기능을 수행하는 반면에, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다는 차이가 있다.

메서드는 그 자체로 메서드가 되는 것이 아니라 객체의 메서드로서 호출할 경우에만 메서드로 동작하고, 그렇지 않으면 함수로 동작한다. 함수로서 호출메서드로서 호출을 구분하는 방법은 함수 앞에 점(.)이 있는지만 보면 된다. 점 표기법이든 대괄호 표기법이든 어떤 함수를 호출할 때 그 앞에 객체가 명시되어있는 경우는 메서드로 호출한 것, 그 외의 모든 경우는 함수로 호출한 것이다.

var obj = {
  method: function (x) { console.log(this.x) }
};
obj.method(1); // { method: f } 1
obj['method'](2) // { method: f } 2

메서드 내부에서의 this

this에는 호출한 주체에 대한 정보가 담긴다. 따라서 어떤 함수를 메서드로서 호출하는 경우 그 주체는 함수명(프로퍼티명) 앞의 객체이다.

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

함수 내부에서의 this

함수로서 호출하는 것은 호출 주체를 명시하지 않고 실행한 것이기 때문에 주체의 정보를 알 수 없다. this가 지정되지 않은 경우 전역 객체를 바라보게 된다.

메서드 내부함수에서의 this

this 바인딩에 관해서는 함수를 실행하는 당시의 주변 환경(메서드 내부인지 함수 내부인지 등)은 중요하지 않다. 오직 해당 함수를 호출할때 함수로서 호출되었는지, 메서드로서 호출되었는지가 중요하다.

var obj1 = {
  outer: function () {
    console.log(this);
    var innerFunc = function () {
      console.log(this);
    }
    innerFunc(); // this = Window(전역객체)
    
    var obj2 = {
      innerMethod: innerFunc
    };
    obj2.innerMethod(); // this = obj2
  }
};
obj1.outer(); // this = obj1

메서드 내부 함수에서 this를 우회하는 방법

자체적으로 내부 함수에 this를 상속할 방법은 없으나 이를 우회할 수는 있다. 바로 변수를 이용하는 방법.

var obj = {
  outer: function () {
    console.log(this); // { outer: f }
    var innerFunc1 = function () {
      console.log(this); // Window { ... }
    }
    innerFunc1();
    
    var self = this;
    var innerFunc2 = function () {
      console.log(self);
    };
    innerFunc2();
  }
};
obj1.outer();

self라는 변수에 this를 저장한 상태에서 호출한 innerFunc2의 경우 self에는 객체 obj가 출력된다.

this를 바인딩하지 않는 함수

ES6에서는 함수 내부에서 this가 전역객체를 바라보는 문제를 보완하고자 this를 바인딩하지 않는 화살표 함수를 새로 도입했다. 화살표 함수는 실행 컨텍스트를 생성할때 this 바인딩 과정이 빠져서 상위 스코프의 this를 그대로 사용할 수 있게 된다.

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

콜백 함수 호출 시 그 내부에서의 this

document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
	.addEventListener('click', function (e) {
  	  console.log(this, e);
	})

addEventListener 메서드는 콜백 함수를 호출할때 자신의 this를 상속하도록 정의되어있다. 따라서 메서드의 점 앞부분이 this가 되는 것이다.
콜백 함수에서 this는 딱 정할 수 없다. 콜백함수의 제어권을 가지는 함수(메서드)가 this를 결정하고, 정의되지 않은 경우 전역객체를 바라본다.

생성자 함수 내부에서의 this

생성자 함수는 어떤 공통된 성질을 지닌 객체들을 생성하는데 사용되는 함수이다. 자바스크립트는 함수에 생성자로서의 역할을 함께 부여했다. new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작한다. 이 경우 내부에서 this는 곧 새로 만들 인스턴스 자신이 된다

var Cat = function (name, age) {
  this.bark = '야옹';
  this.name = name;
  this.age = age;
};
var coco = new Cat('코코', 7);
var nabi = new Cat('나비', 12);
console.log(coco, nabe);

// Cat { bark: '야옹', name: '코코', age: 7 }
// Cat { bark: '야옹', name: '나비', age: 12 }
profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

1개의 댓글

comment-user-thumbnail
2020년 12월 2일

크.. 열심히 하구있네영 화이팅!

답글 달기