자바스크립트에서의 this : 함수와 객체(메서드)를 구분할 수 있는 기능이다.
cf) 다른 대부분의 객체지향 언어에서 this는 class로 생성한 instance 객체를 의미하지만, 자바스크립트에서는 어디서든 사용할 수 있어 함수와 객체(메서드)의 구분이 느슨하다.
자바스크립트에서 this는 기본적으로 실행컨텍스트가 생성될 때, 즉 함수를 호출할 때 결정된다.
1. 전역공간에서의 this
전역공간에서 선언한 변수 a에 1을 할당했는데, window.a 와 this.a 도 모두 1이 출력된다. 이는 자바스크립트의 모든 변수는 특정 객체의 프로퍼티로서 동작하기 때문이다. 정확히는 "전역 변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다."
단, let 과 const 는 전역 변수를 선언하더라고 전역객체의 프로퍼티로 할당되지 않아 window와 this 의 프로퍼티를 호출하면 undefined 가 출력된다.
전역변수와 전역객체
처음부터 전역객체의 프로퍼티로 할당한 경우에는 삭제(delete)가 가능하지만, 전역변수로 선언한 경우에는 삭제가 불가능하다. 이는 사용자가 의도치 않게 변수를 삭제하는 것을 방지 하기 위해 전역변수 선언 시 자동으로 전역객체의 프로퍼티로 할당하면서 추가적으로 해당 프로퍼티의 Configurable 속성(변경 및 삭제와 관련)을 false로 정의해두었기 때문이다.
2. 함수 실행 방법에 따른 this
1️⃣ 함수로 호출: 독립적인 기능 수행
2️⃣ 메서드로 호출 : 자신을 호출한 객체에 관한 동작 수행
함수를 실행하는 방법에는 위와 같이 2가지 방법이 있다.
객체의 메서드로 호출할 때(함수 이름 앞에 객체가 명시되어 있는 경우만 메서드로 동작하고 그렇지 않다면 함수로 동작한다고 생각하면 된다. 함수로 호출할 때 호출주체가 명시 되지 않았기 때문에 this 는 전역객체, 메서드로 호출될 때는 함수명(Property 명) 앞의 객체가 this 가 된다.
3. this Binding
함수 내부에서 this가 전역객체를 바라보는 문제를 해결하는 방법에는 2가지 방법이 있다. 화살표 함수를 사용하면 this를 binding하는 과정 자체가 빠지게 된다. 따라서 화살표 함수를 사용하면 전역객체가 아닌 상위 스코프의 this를 그대로 사용할 수 있다.
1️⃣ 함수 내부에서 this 변수 선언
2️⃣ 화살표 함수 사용
4. 명시적으로 this를 바인딩 하는 방법
① call / apply 메서드의 활용
call 메서드는 메서드의 호출 주체인 함수를 즉시 실행한다. apply 메서드는 call 메서드와 기능적으로 완전히 동일하다. call 메서드는 첫번째 인자를 제외한 나머지 모든 인자들을 호출할 함수의 매개변수로 지정하는 반면, apply 메서드는 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정한다는 차이가 있다.
유사사배열객체(array-like object)에 배열 메서드 적용
객체에는 배열 메서드를 직접 적용할 수 없다. 하지만 key가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티의 값이 0 또는 양의 정수인 객체, 즉 유사배열 객체는 call 또는 apply 메서드를 이용해 배열 메서드를 차용할 수 있다.
단, 문자열의 경우 length 프로퍼티가 읽기 전용이므로 원본 문자열에 변경을 가하는 메서드(push, pop, shift, unshift, splice 등)는 에러를 출력하고, concat 처럼 대상이 반드시 배열이어야 하는 경우에는 에러는 출력되지 않지만 제대로된 결과를 얻을 수 없다. 유사배열객체 또는 순회 가능한 모든 종류의 데이터 타입을 배열로 전환하는 Array.from 메서드가 ES6에 도입 되기도 했다.
② bind 메서드
ES5에서 추가된 기능으로 call 메서드와 유사하지만 즉시 호출하지는 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 하는 메서드이다.
상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
'JavaScript' 카테고리의 다른 글
JS | 클로저(Closure) 와 호이스팅 (0) | 2022.12.05 |
---|---|
JS | 콜백함수(Callback function) (0) | 2022.02.04 |
JS | Execution Context: 실행 컨텍스트 (0) | 2022.02.01 |
JS | Promise 의 3가지 상태 (0) | 2022.01.27 |
JS | What the heck is a Callback? (0) | 2022.01.19 |