2023. 2. 14. 15:30

자바스크립트(Javascript)에서 'this'는 일반적인 언어에서의 'this'와 조금 다릅니다.

이것은 자바스크립 특성때문입니다.

 

 

0. 테스트 코드 작성

설명하기 전에 테스트에 사용할 코드를 작성해 봅시다.

 

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="utf-8">
	<meta http-equiv="Cache-control" content="no-cache">
	<title>Javascript Arrow Function Test</title>
	<script defer="" src="app.js"></script>
</head>
<body>
	<h2>환영!</h2>

	<button id="btnClick">클릭!!</button>
	<button id="btnClick2">클릭2!!</button>
	<button id="btnClick3">클릭3!!</button>
	<button id="btnClick4">클릭4!!</button>

	<br />
	<br />
	<textarea id="txtResult"></textarea>
</body>
</html>

 

app.js

export default class StartUp
{
	
	A = "StartUp A";
	B = "StartUp B";
	
	constructor()
	{
		document.getElementById("btnClick").onclick = this.TestCilck;
		document.getElementById("btnClick2").onclick = this.TestCilck2;
		document.getElementById("btnClick3").onclick = this.TestCilck3;
		document.getElementById("btnClick4").onclick = this.TestCilck4;


		console.log("constructor this A : " + this.A);
		console.log(this);
	}

	TestCilck = () =>
	{
		console.log("TestCilck this A : " + this.A);
		console.log("TestCilck this B : " + this.B);
		console.log(this);
	};

	TestCilck2()
	{
		this.B = "TestCilck2 B";
		console.log("TestCilck2 this A : " + this.A);
		console.log("TestCilck2 this B : " + this.B);
		console.log(this);
	};


	TestCilck3 = () =>
	{
		let fun = function ()
		{
			let tempClass = new TestClass();

			tempClass.Call1(this);
		}

		fun();
	}

	TestCilck4 = () =>
	{
		let objThis = this;

		let fun = function ()
		{
			let tempClass = new TestClass();

			tempClass.Call1(objThis);
		}

		fun();
	}

}


export class TestClass
{
	A = "TestClass A";

	Call1(objThis)
	{
		console.log("TestClass Call2 this A : " + this.A);
		console.log(this);

		console.log("TestClass Call2 objThis A : " + objThis.A);
		console.log(objThis);
	}
}

const app = new StartUp();

 

 

 

1. 자바스크립트의 'this'

자바스크립트의 'this'는 보통 호출한 주체입니다.

(참고 : MDN - JavaScript this )

 

'클릭2!!'를 클릭해보면 'this'가 'StartUp'이 아니고 'button'으로 되어 있습니다.

이것은 'TestCilck2'함수를 호출한 주체가 'button'이여서 그렇습니다.

 

'TestCilck2'에서 'this.B'를 수정해도 'StartUp.B'에 영향을 주지 않는 이유가 여기에 있습니다.

 

일반적인 언어들은 호출 주체가 기준이 아니고 선언 위치가 기준인 걸 생각하면 이상한 동작이라고 할 수 있습니다.

 

 

2. 'this' 유지하기

이럴 때 'this'를 유지하기 위하여 화살표 함수(Arrow function)를 이용할 수 있습니다.

(참고 : MDN - JavaScript 화살표 함수 )

 

화살표 함수 표현(arrow function expression)은 'this'에 대한 바인딩이 없으므로 자신이 원래 소속된 'this'를 가지게 됩니다.

 

'TestCilck'이 화살표 함수입니다.

 

그래서 'TestCilck'의 'this'는 'StartUp'이 유지됩니다.

 

 

3. 익명 함수(Anonymous function)에서의  'this' 

위와 같은 문제 때문에 익명 함수(Anonymous function)에서 'this'를 사용하면 'this'가 달라집니다.

이런 경우 'this'를 전달하려면 아래와 같이 변수에 담아야 합니다.

TestCilck4 = () =>
{
    let objThis = this;

    let fun = function ()
    {
        let tempClass = new TestClass();

        tempClass.Call1(objThis);
    }

    fun();
}

 

 

마무리

테스트 프로젝트 : github - dang-gun/HtmlJavascriptSamples/JavascriptArrowFunction

 

이것도 'var'문제와 함께 짜능 나게 만들던 문제였는데 버전이 올라가면서 해결되는 거 보면 다행이다 싶네요.

클래스 문제는 영원히 해결될 거 같지 않지만 그래도 많이 편해진 건 사실입니다 ㅎㅎㅎ