안녕하세요. Tay 입니다.
자바스크립트에서 this 개념은 매우 중요합니다. 자바스크립트의 this 는 타 언어와 개념이 조금 다릅니다.
어떻게 보면 this 는 실행되는 흐름? 문맥? 이라고 볼 수 있습니다.
this
- 함수 내부로 전달되어 호출한 객체를 참조하는 this 인자
- 호출 패턴에 따라서 다른 바인딩
호출 패턴에 따른 바인딩
1. 객체의 메서드 호출 할때 this 바인딩
1) index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="obj_method.js"></script>
</body>
</html>
2) obj_method.js
let myObj = {
name: "kim",
sayName: function() {
console.log(this.name);
}
};
let otherObj = {
name: "lee"
};
otherObj.sayName = myObj.sayName;
myObj.sayName();
otherObj.sayName();
- 객체 myObj 에는 메서드 sayName 이 있다.
- 객체 otherObj.sayName 메서드를 생성하고, myObj.sayName 메서드를 할당했다.
- myObj.sayName 과 otherObj.sayName 메서드의 출력 값을 확인해보자.
결과 :
각각의 sayName 메서드는 객체.name 프로퍼티 값을 출력했다.
이때 this 는 해당 메서드를 호출한 객체로 바인딩 된다.
2. 함수를 호출할 때 this 바인딩
1) index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- <script src="obj_method.js"></script> -->
<script src="func.js"></script>
</body>
</html>
2) func.js
var firstNm = "geuntae";
console.log(firstNm);
console.log(window.firstNm);
let sayFullNm = () => console.log(`kim${this.firstNm}`);
sayFullNm();
- 전역변수 firstNm 을 선언한다. (전역변수는 전역객체의 프로퍼티다.)
- 전역 객체 window 안에 firstNm 을 콘솔로 찍는다.
- sayFullNm 함수 안에 this 는 어떤 것을 가르키는지 확인해본다.
결과 :
firstNm 이 두번 출력 되고, fullNm 이 한번 출력됐다.
이유는 sayFullNm 함수 내부의 this 는 전역객체로 바인딩 되었고, 전역객체 window 는 firstNm 프로퍼티가 되어 출력된 것이다. 즉, this 는 전역객체 window 를 바라보고있다.
해설 :
겉에 window 전역객체가 있다고 생각하면 이해가 편하다.
전역변수는 전역객체의 프로퍼티가 되고, this 는 전역객체를 바라보기때문에 window 를 가르킨다.
* 그림이 엉망이지만, 내용에 집중해주세요.
3. 내부 함수를 호출할 때 this 바인딩(this 와 that)
1) index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- <script src="obj_method.js"></script> -->
<!-- <script src="func.js"></script> -->
<script src="inner_func.js"></script>
</body>
</html>
2) inner_func.js
var value = 100;
let myObj = {
value: 1,
func1: function() {
this.value += 1;
console.log(`func1() called. this.value : ${this.value}`);
func2 = function() {
this.value += 1;
console.log(`func2() called. this.value : ${this.value}`);
func3 = function() {
this.value += 1;
console.log(`func3() called. this.value : ${this.value}`);
};
func3();
};
func2();
}
};
myObj.func1();
- 전역변수 value 를 선언한다.
- myObj.func1 메서드를 실행한다.
- func2 내부 함수 호출을 실행한다.
- func3 내부 함수 호출을 실행한다.
위 내용을 보고 결과가 어떻게 되는지 생각해보자.
결과 :
결과가 2, 3, 4 가 아닌 2, 101, 102 로 출력됐다. 그 이유가 뭔지 알아보자.
이유 :
myObj.func1 은 메서드 호출이었다.
그렇기때문에 func1 을 호출한 객체로 this 가 바인딩 된다.
중요!!
하지만 func2, func3 는 내부 함수 호출이었다.
함수 호출에서의 this 바인딩 특성은 내부 함수를 호출했을 경우에도 그대로 적용된다.
That
부모 함수의 this 를 내부 함수가 접근 가능하도록 저장해주는 변수
※ 꼭 이름이 that 이 아니어도 된다. 다만, 암묵적인 룰이다.
위 inner_func 의 코드를 that 으로 수정해서 원하는 2, 3, 4 가 출력되도록 변경해보자.
변경 전 | 변경 후 |
var value = 100;
let myObj = {
value: 1,
func1: function() {
var that = this;
this.value += 1;
console.log(`func1() called. this.value : ${this.value}`);
func2 = function() {
that.value += 1;
console.log(`func2() called. this.value : ${that.value}`);
func3 = function() {
that.value += 1;
console.log(`func3() called. this.value : ${that.value}`);
};
func3();
};
func2();
}
};
myObj.func1();
func1 메서드 호출 이후, func1의 this 를 that에 삽입하여 that을 사용했다.
결과 :
내부 함수에서 myObj 의 value 값을 올리는 것을 확인할 수 있다.
정리!!
- 객체 메서드 호출시 this 는 해당 매서드를 호출한 객체로 바인딩 된다.
- 함수 호출시 전역 객체로 this 바인딩 된다.
- 내부 함수 호출시 전역 객체로 this 바인딩 된다.
- 부모 함수의 this 를 저장하는 관례는 that 이다.
이 글은 개인 공부목적으로 작성되었습니다.
정보가 잘못 되거나 궁금한 사항은 댓글로 부탁드립니다!! 읽어주셔서 감사합니다.
'JavaScript > Basic-Javascript' 카테고리의 다른 글
자바스크립트 정리하며 배우기[24] - This[3] : 생성자 함수에 new 를 붙이지않고 호출 할 경우 와 일반 함수에 new 를 붙여서 호출 할 경우 에러 (0) | 2020.03.20 |
---|---|
자바스크립트 정리하며 배우기[23] - This[2] : 생성자 함수를 호출할 때 this 바인딩 (0) | 2020.03.19 |
자바스크립트 정리하며 배우기[21] - Arguments : 유동적인 함수 만들기 (0) | 2020.02.20 |
자바스크립트 정리하며 배우기[20] - 내부 함수(inner function) (0) | 2020.02.03 |
자바스크립트 정리하며 배우기[19] - 콜백 함수(callback) (0) | 2020.02.03 |