-
[JavaScript] 자바스크립트 this의 모든 것Web/JavaScript 2021. 5. 15. 21:12
this란 무엇인가?
C++, JAVA 등 다양한 프로그래밍 언어에서도 this가 존재하는데, 여기서 this는 객체 자신을 나타내는 포인터, 레퍼런스다.
하지만 자바스크립트에서 this는 함수의 호출 맥락(Context)를 의미한다. 즉 함수를 어떻게 호출하냐에 따라 this가 가리키는 대상이 달라질 수 있다는 것이다. 함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결 시켜주는 역할을 한다.console.log(this); // window function func1() { console.log(this); } func1(); // window
우선 브라우저의 개발자 도구에서 this를 출력 해보면 전역 객체인 window 객체를 출력한다. (node.js에서는 this를 출력하면 빈 객체 { } 가 나온다) 뿐만 아니라 func라는 함수 안에서 this를 출력 해보아도 똑같이 window 객체를 출력한다.
더보기strict 모드에서는 this에 디폴트 바인딩이 없기 때문에 undefined를 출력한다.
"use strict"; function myFunction() { return this; } console.log(myFunction()); //undefined
메소드에서 this
const obj = { func2: function () { console.log(this); // obj 객체를 출력 } } obj.func2();
위의 코드를 보면 obj라는 객체의 메소드 func2에서의 this는 func2가 소속 되어있는 객체 obj를 가리키는 것을 알 수 있다. 사실 처음 설명한 코드와 같은 원리인데, 처음 설명한 func1는 window라는 객체의 메소드 window.func1()라고도 볼 수 있기 때문에 func1 안의 this는 window를 가리켰던 것이다.
생성자에서 this
생성자 안에서 this는 그 생성자가 만든 객체를 나타낸다.
function func () { console.log(this); } func(); // window const A = new func(); // func { }
다양한 형식의 메소드와 this를 출력해 보았다.
var obj = { func: function() { return this; }, func2: function() { var obj2 = { func: function() { return this; } } return obj2.func(); }, func3: function() { function func4() { return this; } return func4; }, func5: () => { return this; } } function func6() { return this; } console.log(obj.func()); // obj console.log(obj.func2()); // obj2 console.log(obj.func3()); // func4 console.log(obj.func5()); // { } console.log(func6); // func6 console.log(new func6()); // func5 {}
때문에 만약 함수를 생성자를 사용하지 않고 호출을 한다면 해당 함수에서 this 는 전역 객체인 window를 가리키므로 원치않는 데이터 변경이 되지 않도록 주의해야한다.
var data = 'important'; function func(value) { this.data = name; } var tmp = func('Hello'); console.log(window.data); // Hello
이벤트 핸들러 안의 this
이벤트 핸들러에서 this는 이벤트를 받는 HTML 요소를 가리킨다.
const btn = document.querySelector('#btn'); btn.addEventListener('click', function () { console.log(this); //#btn });
함수 바인딩 (apply, call, bind)
일반적으로 객체와 메소드는 Master-Slave 관계를 가지고 있다.
하지만 함수의 메소드인 bind, apply, call를 사용한다면 Master인 객체를 (this의 값을) 제어 할 수 있다.
그렇다면 이 세가지 메소드는 어떤 차이가 있는지 알아보자.1. apply
함수의 메소드인 apply를 이용하면 해당 함수에서 사용되는 this가 어떤 객체를 나타 낼 것인지 직접 설정한다.
var o = {}; var p = {}; function func(){ console.log(this); } func(); // window func.apply(o); // o { } func.apply(p); // p { } func(); // window
apply를 사용하더라도 실제 func가 속한 객체를 바꾼 것이 아니기 때문에 마지막에 다시 호출한 func()에서는 다시 window 객체를 가리킨다.
2. call
apply와 call 두 메소드는 거의 흡사하다. 둘의 유일한 차이점은, 바인딩 할 함수에 인자가 있을 때, 파라미터로 배열을 넣냐, 여러개의 파라미터를 값으로 넣냐다. apply는 배열을 인자로 받고, call은 다수의 파라미터를 인자로 받는다. 아래의 예시를 보자.
window.num = 0; function sum(num1, num2){ return console.log(this.num + num1 + num2); } const obj = { num : 100 } sum(1, 2); // 3 sum.call(obj, 1, 2); // 103 sum.apply(obj, [1, 2]); // 103
예시를 보면 call이나 apply나 인자의 형태만 다를 뿐 바인딩 된 객체나 전달 된 인자들은 모두 같다는 것을 알 수 있다.
3. bind
bind는 새롭게 바인딩 한 함수를 만든다. 여기서 주의 할 점은 bind()는 call(), apply()와 같이 함수가 가리키고 있는 this를 바꾸지만 호출되지는 않는다.
window.num = 0; function sum(num1, num2){ return console.log(this.num + num1 + num2); } const obj = { num : 100 } const sum2 = sum.bind(obj); // 함수가 호출되지 않기 때문에 출력 없음 sum(1, 2); // 출력: 3 sum2(1, 2); // 출력: 103
'Web > JavaScript' 카테고리의 다른 글
[JavaScript] Event의 이해 (0) 2021.08.15 [JavaScript] 스코프(Scope)와 클로져(Closure) (0) 2021.05.25 [JavaScript] 실행 컨텍스트와 스코프 체인 (0) 2021.05.13 [JavaScript] 호이스팅 이란? (0) 2021.05.13 [JavaScript] 번들러(Bundler)란? (0) 2021.05.13