함수 내부에 위치한 this의 값은 함수의 실행문에 의해 결정되고 함수 밖(전역 공간)에 위치한 this값은 전역객체가 된다. 함수의 실행문에 의해 this의 값이 결정되는 4가지의 경우와 그 특징들을 알아보자.
*전역객체는 브라우저에서는 window, node.js환경에서는 global이다.
우선 전역 공간에서의 this의 값부터 살퍼보자. 아래 예시에 나온 모든 this값은 모두 전역공간에 정의되어있으므로 window이다.
특히 24, 25번 코드에 있는 객체 내부에 선언된 this값에 주의하자. 함수 내부에 포함되어있지 않기 때문에 this의 값은 전역 객체, 즉 window가 된다.
단, 이러한 this사용은 매우 좋지 않다. this는 함수 내부에서 실행 방식에 따라 다른 값을 가지며 코드의 재사용성을 높여효율적으로 만들어줄 수 있다. 위와 같은 사용은 지양해야한다.
이제 함수 내부에 위치한 this의 값을 판별하기 위한 함수 실행 방식을 살펴보자.
1. 일반 함수 실행
함수의 실행문이 '함수()'의 기본적인 형태로 실행되는 경우를 말한다.
21번 코드에서 person1.body라는 함수가 foo변수에 저장되었다.
이 함수는 person1 객체 내부의 body 프로퍼티 안에 선언된 함수이지만 이 함수의 this값을 결정하는 데 아무런 영향도 미치지 않는다.
23번 코드에서 foo함수는 일반 함수 실행문으로 실행되고있다.
따라서 17번 코드의 this는 모두 전역객체가 된다.
<strict mode>
strict mode는 strict mode를 사용할 범위의 상단에 "use strict";를 선언하여 실행할 수 있다.
stict mode에서는 위 예제와 같은 코드이지만 this의 값은 undefined가 된다.
* this라는 키워드는 함수의 실행 상황에 맞게, 유연하게 그 값이 변화하여 함수의 재사용성을 높일 목적으로 사용되는데, this의 값이 window가 되는 것은 대부분 개발자가 의도한 대로 실행되지 않은 경우이다.
strict mode에서는 위 상황에서 에러를 발생시키기 때문에 이러한 경우를 방지할 수 있다.
** 일반 함수 실행 방식에서 this의 값 **
non-strict mode에서는 window
strict mode에서는 undefined
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
Strict mode - JavaScript | MDN
Strict mode Note Sometimes you'll see the default, non-strict mode referred to as "sloppy mode". This isn't an official term, but be aware of it, just in case. JavaScript's strict mode, introduced in ECMAScript 5, is a way to opt in to a restricted variant
developer.mozilla.org
2. (점 표기법 - Dot Notation)
함수가 특정 객체의 메소드로써 호출되는 경우 객체 + "." + "함수"의 형태로 실행된다.
함수가 실행될 때 앞에 "."이 있다면 이 값이 함수의 호출 주체이며 해당 함수의 this는 "."앞에 있는 값을 참조한다.
위 코드에서 23번과 24번에서 실행되는 코드는 12번-14번에 위치한 코드로 동일하다.
23번에서는 일반함수로 실행되고있어 this의 값은 전역 객체가 된다.
24번에서 func 함수는 person1객체 내부의 body메서드 함수로써 실행되고 있으므로 this는 person1이 된다.
3. 명시적 바인딩(Explicit Binding)
this의 값을 명시적으로 지정하여 실행하는 방법이다.
call, apply, bind 메소드를 활용한다.
.call() | .apply() | .bind() |
함수를 실행한다 | 함수를 실행한다 | 명시된 인자들로 새로운 함수를 만들어 반환한다 |
첫번째 인자가 this, 두 번째 인자부터 메소드를 사용한 함수의 매개변수로 전달된다. | 첫 번째 인자가 this, 두 번째 인자는 메소드를 사용한 함수의 매개변수로 전달할 인자들을 묶은 배열이다 | 첫번째 인자가 this, 두 번째 인자부터 메소드를 사용한 함수의 매개변수로 전달된다. |
인자의 개수에 제한이 없다. | 인자의 개수는 2개로 제한된다. | 인자의 개수에 제한이 없다. |
- call 메소드와 bind 메소드는 인자 선언이 유사하다.
- bind 메소드는 함수가 실행되는 것이 아니라 this값과 인자들을 저장해 새로운 함수를 반환한다.
- 27번-28번 코드처럼 bind할 때 인자의 일부 값을 저장하고 함수를 실행할 때 나머지 인자를 넘겨주는 것이 가능하다. (partially applied functions)
- 28번 코드에서 보이듯이 bind메소드를 통해 복제된 함수가 저장된 변수가 실행되는 구문은 마치 일반 함수 실행처럼 보인다. 해당 함수의 this 값이 window가 아니라면 상위 코드에서 bind를 이용한 명시적 this지정 방식인지 알아봐야한다.
- 해당 메소드들의 첫번째 인자(this)로 null 또는 undefined가 지정되면 this의 값은 전역객체가 된다.
4. new keyword (생성자 함수)
new 키워드를 이용해 함수를 실행할 경우, this의 값은 빈 객체( [ ] )가 된다.
23번의 this는 [](빈 객체)
23번의 this는 [1, 2, 3]
setTimeout 메소드의 콜백함수 내부의 this 값 결정
arrowFunction
'Programming > JavaScript' 카테고리의 다른 글
[JavaScript] 원시값과 참조값 (Primitive & Reference) (2) | 2021.03.30 |
---|---|
[Javascript] Executive context(실행 콘텍스트) (0) | 2021.03.30 |
[javaScript] map 메소드 (0) | 2021.03.22 |
[JavaScript] textContent / innerText / innerHTML (0) | 2021.03.16 |
[JavaScript] var vs. let vs. const (0) | 2021.03.15 |