Javascript에서의 this

Posted by 열정보이
2019. 4. 20. 21:22 Javascript

 

Javascript에서 this는 상황에 따라 바인딩하는 객체가 달라진다.

그렇기 때문에 함부로 사용해서는 안되는데, 그 상황들을 알아보자.

 

<script>

    var myObject = {
        name : 'foo',
        sayName : function () {
            console.log(this.name); // this.name == myObject.name
        }
    };

    var otherObject = {
        name : 'bar'
    };

    otherObject.sayName = myObject.sayName;

    myObject.sayName();
    otherObject.sayName();

</script>

 

위와 같은 코드의 결과는 다음과 같다.

 

 

메서드안에서의 this

 

객체의 프로퍼티 값으로 함수가 올 경우 Javascript에서는 '메서드' 라고 부른다.

이러한 '메서드안에서 this는 자신을 포함하고 있는 객체' 를 가르킨다.

 

 

그렇기 때문에 sayName을 호출하게 되면, this는 myObject로 바인딩되어,

myObject.name과 otherObject.name이 출력되는 것이다.

 

 

 

함수안에서의 this

 

그렇다면 또 다른 상황을 보도록 하자.

 

<script>

    var value = 100;

    var myObject = {
        value : 1,
        func1 : function() {
            this.value += 1; // this.value == myObject.value;
            console.log('func1() called. this.value : ' + this.value);

            func2 = function() {
                this.value += 1; // this.value == window.value;
                console.log('func2() called. this.value : ' + this.value);

                func3 = function() {
                    this.value += 1; // this.value == window.value;
                    console.log('func3() called. this.value : ' + this.value);
                }
                func3();
            }
            func2();
        }
    };

    myObject.func1();

</script>

 

함수안에서의 this는 전역 객체인 window에 바인딩된다.

위 코드의 결과를 보도록 하자.

 

 

func1() 같은 경우 객체의 프로퍼티로 선언된 메서드이기 때문에 this는 myObject로 바인딩되지만, func2() 와 func3()은 메서드가 아닌 함수 표현식으로 선언된 함수이다.

그렇기 때문에 this는 myObject가 아닌 window인 전역 객체로 바인딩 된다.

그 결과 window.value 의 값이 증가하는것을 볼 수 있다.

 

 

생성자 함수안에서의 this

 

또 하나의 경우를 보도록 하자.

 

<script>
    var name = 'java';
    function Person(name){
        this.name = name;
    }
    var foo = new Person('foo');
    console.log(foo.name);
    console.log(window.name);
</script>

 

위 결과는 다음과 같다.

 

 

함수에서 사용하는 this는 분명 window로 바인딩된다고 하였는데, window.name의 값은 바뀌지 않았다.

그 이유는 생성자 함수에서의 this는 또 다른 결과를 가져오기 때문이다.

 

먼저 생성자 함수가 동작하는 방식에 대해 이해를 해보자.

new 연산자를 이용해 함수를 호출하게 되면 다음과 같은 순서로 동작된다.

 

 

그렇기 때문에 new를 이용해 함수를 호출하게 되면, this는 새로 생성된 객체에 바인딩된다.

그래서 함수안의 this임에도 불구하고, new를 이용해 호출하였기에 window.name이 변하지 않고 java를 유지할 수 있는것이다.

 

그렇다면 여기서 우리는 조심해야 되는 사항을 알 수 있다.

'함수를 new를 붙여서 호출할 때와 그렇지 않을 때 this가 바인딩하는 객체가 다르다는 점' 이다.

 

new를 사용하지 않고, 일반 함수로 호출하게 되면 this는 window에 바인딩되며, 위와 같은 경우 return 값이 명시되어있지 않기 때문에 undefined를 반환한다.

new를 사용하여 생성자로 함수를 사용할 경우, return  값이 명시되어 있지 안다면 새로 생성된 객체를 반환한다.

 

그래서 Javascript에서 함수를 객체를 사용하기 위한 생성자로 사용할 경우 약속이 존재한다.

바로 첫 글자를 대문자로 명시하는 것이다.

 

 

 

지금 까지 여러 상황에서의 this에 대해 알아보았다.