Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

함수호출 방식에 따른 this의 바인딩에 대해서...

더글라스 크락포드의 자바스크립트 핵심 가이드를 공부하면서 Javascript에는 4가지 함수호출 패턴이 있다는 것을 알게 되었고 이 패턴에 따라서 함수내의 this의 값은 달라지게 됩니다. Javascript에서 this와 객체의 바인딩은 호출시에 일어납니다.

  • 메서드 호출패턴
  • 함수 호출패턴
  • 생성자 호출패턴
  • apply 호출패턴
Javascript에서 this의 바인딩은 다룰때마가 헷갈리는 문제이므로 기본이 되는 내용을 공부한 김에 정리해 둡니다.


메서드 호출 패턴
여기서 메서드는 함수가 객체의 속성(멤버함수)로 저장되어 있는 경우에 이 함수를 메서드라고 부르고 메서드를 호출할때 this는 객체에 바인딩 됩니다.

var test = {
    x: 100,
    showX: function() {
        alert(this.x);
    }
}

test.showX();   // 100


함수 호출 패턴
함수가 객체의 속성이 아닌 경우입니다. 이렇게 호출했을때 this는 전역객체(window객체를 의미합니다.)에 바인딩됩니다.

var x = 100;
var test = function() {
    alert(this.x);
}

test();  // 100

더글라스 크록포드는 이런 특성이 자바스크립트라는 언어 설계상의 오류라고 지적합니다. 왜냐하면 내부함수를 호출했을때 this는 외부함수의 this변수에 바인딩되어야 하지만 그렇지 않고 전역객체로 바인딩 됩니다.


var x = 1;
var test = {
    x: 100,
    showX: function() {
        alert(this.x);
    },
    whatisX: function() {
        var show = function() {
            alert(this.x);
        }
        show();
    }
}

test.whatisX();   // 1


이 코드를 실행했을때 whatisX의 show()는 함수호출되었기 때문에 this.x가 test.x가 아닌 window.x가 되어서 100대신에 1이 찍히게 됩니다. test.x를 가르키게 하려면 this변수를 다른 변수에 할당해 놓고 사용하여야 합니다.


생성자 호출 패턴
여기서 생성자가 의미하는 것은 new를 써서 인스턴스를 만들어서 쓰는 함수를 의미합니다. 일반적인 함수는 new를 쓸수도 있고 안쓸수도 있지만 prototype으로 확장을 함으로써 new를 써서 사용하도록 하고 파스칼형태로 첫글자를 대문자로 써줌으로써 생성자함수라는 것을 나타내줍니다.

var Test = function(x) {
    this.temp = x
}

Test.prototype.getTemp = function() {
    alert(this.temp);
}

var t = new Test(100);
t.getTemp();  // 100

이렇게 사용하면 new로 만든 객체에 대해서 this가 바인딩 됩니다.


apply 호출 패턴
apply함수는 첫번째 파라미터가 this에 바인딩될 객체이고 두번째 파라미터에 배열로 함수에 넘겨줄 파라미터를 지정합니다. 첫번재 파라미터가 null이나 undefined이면 전역객체에 바인딩 됩니다.

var x = 1; 
var test = {
    x: 100,
    showX: function() {
        alert(this.x);
    }
}

test.showX.apply(null);   // 1

메서드 호출패턴에 사용했던 소스에 apply를 적용했습니다. 첫번째 파라미터로 null을 넘겨주었으므로  this가 전역객체에 바인딩되어서 100이 아닌 1이 찍힙니다.

2010/02/24 03:19 2010/02/24 03:19