[JavaScript] 자바스크립트 this란?
'this' keyword
객체지향언어에는 this
라는 키워드가 대부분 존재합니다.
자바스크립트에도 this
가 존재하는데, 이는 다른 객체지향언어와는 다르게 동작합니다.
다른 언어들처럼 함수를 선언할 때 this
에 바인딩할 객체가 결정되는 것이 아니고, 함수가 호출되는 방식에 따라 동적으로 바인딩할 객체가 결정됩니다. 이는 자바스크립트 인터프리터가 코드를 실행하면서 생성하는 Execution Context에 기인합니다.
function foo() {
const a = 2;
this.bar();
}
function bar() {
console.log(this.a);
}
foo(); //undefined
위의 예시에서의 foo의 this
는 함수의 Lexical Scope가 아닌 Global Scope를 참조하고 있습니다.
이는 Global Scope가 foo의 Execution Context이기 때문입니다.
How 'this' works in JavaScript
Execution Context에는 Variable Object, Scope Chain, 그리고 this 에 대한 정보를 저장합니다.
Execution Context는 함수 호출 시 새로 생성되며, 동시에 this
값을 정합니다. 함수가 호출될 때, ECMAScript는 Arguments List와 thisArg 객체를 전달한다. 이 때 아래의 과정을 통해 this
값을 결정합니다.
strict mode
에서 정의된 함수일 경우,this
는 thisArg가 된다.- thisArg가 null | undefined 일 경우,
this
는 global Object가 된다. - Type(thisArg) 값이 객체가 아닌경우,
this
는 toObject(thisArg) 가 된다.- Type() 함수는 ECMAScript 내부 함수로, 변수의 Type을 리턴합니다.
- toObject() 함수는 변수를 Boolean, Number, String, Object 형으로 변환합니다.
- 위의 과정을 거치고도
this
값이 정해지지 않았다면,this
는 thisArg가 된다.
call, apply, bind 모두 thisArg 수정함으로써 this
값을 바인딩하는 것입니다.
그렇다면, thisArg는 어떻게 결정되는 것일까? 이는 함수 호출 과정의 6번 단계와 관계가 있습니다.
-
Type(ref) 값이 reference 라면,
- isPropertyReference(ref) 를 통해 ref가 object | primitive wrapper object(Stirng, Boolean, Number 등의 객체) 라면 thisArg는 getBase(ref) 값이 된다.
- 그렇지 않다면, thisArg는 getBase(ref) 값의 ImplicitThisValue() 값이 된다.
위의 과정만 봐서는 this
가 언제 어떻게 바인딩되는지 알기 어렵습니다. 그래서, 흔히 발생하는 케이스를 통해 간단한 규칙을 소개하겠습니다.
Simple Rules to ‘this’ in JavaScript
new
키워드와 함께 함수를 호출하면,this
는 아예 새로운 객체가 된다.
function Person(age) {
console.log(this)
this.age = age
console.log(this)
}
const person = new Person(22)
// {}
// { age: 22 }
apply
,call
,bind
가 함수의 호출/생성에 사용되면,this
는 인수로 전달된 객체가 된다.
function foo() {
console.log(this)
}
const obj {
value: 5
}
const example = foo.bind(obj)
example() // { value: 5 }
foo.call(obj) // { value: 5 }
foo.apply(obj) // { value: 5 }
obj.method()
와 같이 함수를 호출하면,this
는obj
가 된다.
const obj = {
value: 5,
print: function() {
console.log(this)
}
}
obj.print() // { value: 5, print: f }
- 자유 함수(위의 조건 없이)로 호출되면,
this
는 전역 객체(브라우저에서는window
)가 된다. 단,strict mode
에서는undfined
가 된다.
function foo() {
console.log(this);
}
//브라우저에서 호출되면
foo() // Window { stop: f, open: f, alert: f, ... }
// 이 규칙은 3번 규칙과 동일합니다. 객체의 메소드로 선언되지 않은 함수는 자동으로 전역 객체의 property가 됩니다.
// foo()와 같이 함수를 호출하는 것은, window.foo()로 해석됩니다.
- 위의 4가지 규칙 중, 다수가 적용되면 상위 규칙이 승리한다.
- ES6에 새로 정의된 화살표 함수인 경우, 위의 규칙을 무시하고 Lexical Scope를 따라 상위 스코프의
this
값을 받는다.
참고자료
Author And Source
이 문제에 관하여([JavaScript] 자바스크립트 this란?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@arski/JavaScript-자바스크립트-this란저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)