본문 바로가기

IT/javascript

[javascript] this 란

1. this

javascript의 this는 다른 언어의 this와 동작하는 방식이 조금 다릅니다.
javascript에서 대부분의 경우 this는 함수를 호출하는 방법에 따라 결정됩니다.

즉, 함수를 호출 할 때 마다 this가 가리키는 값이 다를 수 있습니다. 

 

2. 전역에서 this를 호출 했을 경우

console.log(this); // window
전역에서의 this는 기본적으로 window 객체를 가리킵니다. 

 

3. 함수 안에서 this를 호출 했을 경우

function doSomething(){
    return this; 
}

console.log(doSomething()); // window
console.log(window.doSomething()); // window
this를 결정하는 건 대부분 함수가 호출될 때, 이루어집니다. (bind 함수와 arrow 함수 제외 )
그리고 함수를 호출한 객체가 무엇이냐에 따라 this가 결정됩니다.

 

4.  메소드에서 this를 호출 했을 경우

function doSomething(){
    return this; 
}

var obj = {
    doSomething : doSomething
};

console.log(doSomething()); // window
console.log(obj.doSomething()); // obj
this를 결정하는 것은 함수를 호출한 객체가 무엇이냐에 따라 달라진다고 했었습니다. 따라서
doSomething 함수를 obj의 메소드로 등록하고 obj.doSomething()을 호출 했기 때문에 this는 obj가 됩니다.
(전역에서 선언되었을 경우 함수라 부르고, 객체에 속한 함수를 메소드라고 부릅니다.)
하지만 여기서 주의해야 할 점이 있습니다. 

 

var a = 10;
var obj = {
    a : 20,
    doSomething : function (){

        function func(){
            console.log(this.a); // 10
        }
    
        func();
    
        console.log(this.a); //20
    }
};

obj.doSomething();
doSomething 메소드 안에서 선언된 func 함수지만 호출해보면 console.log(this.a)에 10이 찍힙니다. 
이유는 obj 객체와 func 함수는 아무런 관련이 없는 함수이기 때문입니다.
위에서 설명했다시피 함수에서의 this는 기본적으로 window입니다.

그래서 메소드 내 함수에서 this를 가리키려면 self 변수에 객체의 this를 저장해서 접근합니다. 
var a = 10;
var obj = {
    a : 20,
    doSomething : function (){
        var self = this; // obj this를 저장한다.

        function func(){
            console.log(self.a); // 20
        }
    
        func();
    
        console.log(this.a); //20
    }
};

obj.doSomething();

 

5. 생성자에서 this를 호출 했을 경우

var age = 10;

function Person(){
    console.log(this.age);
}

var p = new Person(); 

Person();


/*

출력
--------
undefined
10

*/
Person함수는 window객체에 속한 함수입니다. 그래서 그냥 호출하면 this.age는 전역 변수의 age 값을 가리키게 됩니다.
하지만 Person 함수를 new 키워드를 통해 생성하면 새로운 객체가 만들어지면서 this는 window가 아닌 생성한 객체를 가리키게 되고, 함수의 내용은 생성자가 됩니다. 

그래서 생성자 호출 시 새로 생성한 객체에는 age 값이 없기 때문에 undefined가 출력됩니다.

 

6. bind 메서드

ECMAScript 5에서 Function.prototype.bind를 새롭게 도입했습니다.
bind 메서드란 함수 내의 this를 영구적으로 지정하는 메서드입니다.
var a = 10;
function func(){
    console.log(this.a);
}

func(); // 10

//func함수의 this를 obj 객체로 바인딩한다.
var obj = { a : 20 };
var new_func = func.bind(obj);

new_func(); // 20


var obj2 = { a : 30 };
var new_func2 = new_func.bind(obj2); // obj로 바인딩 된 함수를 다시 obj2로 바인딩한다.

//이미 바인딩 된 함수의 this는 변하지 않는다.
new_func2(); // 20  

 

7. 에로우 함수

에로우 함수에서 this는 자신을 감싼 lexical context입니다. 전역에서는 window를 가리킵니다.
에로우 함수 또한 한번 this를 지정하면 변하지 않습니다.
var func = (() => {
    console.log(this);
});
func(); // window


//obj의 func 메소드로 대입
var obj = {func: func};
obj.func(); // window


//obj 객체로 this를 바인딩
var new_func = func.bind(obj);
new_func(); // window

 


참조

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this