출처 : http://beizix.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Function-%EC%9D%98-%EB%B9%84%EB%B0%80-this




프로그래밍 언어에서 유효범위(scope)는 변수의 접근성과 생존 기간을 제어합니다. 자바스크립트에서 유효범위는 이해하기 까다로운 개념입니다. 중요한 것은 유효범위 내에서 코드를 실행시키는 컨텍스트(context : 문맥)입니다. 사용자는 this 키워드를 통해 컨텍스트에 접근할 수 있습니다. 


이번 포스팅의 키워드는 다음과 같습니다. 

  • 함수 유효범위(scope)
  • 컨텍스트(context)
  • this
  • call
  • apply


함수 유효 범위


자바스크립트의 블록 구문({ })은 블록 유효범위를 지원하는 것처럼 보이지만, 실은 함수 유효 범위만을 제공합니다.


    // =============================

    //  블록 유효 범위와 함수 유효 범위

    // =============================


if (true) { 

    var msg = 'hello'; 
} 

alert(msg); // "hello" 

function sayHello () { 
    var greeting = 'hello'; 
} 

alert(greeting); // undefined


위의 예처럼 블록 내에서 선언된 변수는 (우리의 예상과 달리) 블록 외부에서 유효하지만, 함수 내에서 정의된 변수는 함수 외부에서 유효하지 않습니다. 자바스크립트에서 지역적 유효범위의 설정은 함수를 통해서만 가능합니다.  


컨텍스트(Context)


이렇게 작성된 코드는 어떤 형태로든 항상 컨텍스트(context) 에 속하게 됩니다. 컨텍스트는 그 속에서 코드가 돌아가는 객체를 의미합니다. 이 개념은 다른 객체지향 언어에도 있지만 자바스크립트 만큼 혼란스럽지는 않습니다. 컨텍스트는 this 키워드를 통해 참조할 수 있습니다. 


this 


this 키워드는 함수의 유효범위 내에서 현재 객체에 접근하기위한 수단으로 쓰입니다. 함수를 어떻게 호출했느냐에 따라 this 키워드가 가리키는 객체(context)가 달라지기에 사용자는 혼란을 겪게 됩니다. 그 예를 하나씩 살펴보도록 하겠습니다. 


우선, function 을 단지 호출용 함수로 사용했다면, 이때 this 는 전역객체를 가리킵니다.


    // =============================

    //  function 내부 컨텍스트

    // =============================


function f () {
    console.log(this); 
}; 


f(); // window


함수를 특정 객체의 속성에 담아 사용하는 경우 이를 메서드라고 부릅니다. 이때 this 는 메서드를 담은 객체를 가리킵니다. 


    // =============================

    //  메서드 내부 컨텍스트

    // =============================


var oj = {

    method : function () {

      console.log(this);
    }
};
oj.method();  // Object { method : function () {...}}

        

  // 함수 내에 static 함수를 정의한 경우

  var a = function () {};

  a.b = function () { console.log(this); };


  a.b();  // function () {} <= a function 을 가리킴. 


하지만, 메서드 내부에 담긴 중첩 함수 안에서 this 는 다시 전역객체를 가리킨다. 


    // =============================

    //  메서드 내부에 중첩된 함수의 컨텍스트

    // =============================


var oj = {
    method : function () {
        function inner () {

            console.log(this);  // window

        }

  (function () {

        console.log(this);  // window

  })();

};  


함수를 new라는 전치 연산자와 함께 호출하면, 호출한 함수의 prototype 속성값에 연결된 (숨겨진) 링크를 갖는 객체가 생성되고, this 는 이 새로운 객체에 바인딩됩니다. 


    // =============================

    //  생성자 함수 내부 컨텍스트

    // =============================


var Obj = function (str) {
    this.status = str;
};

Obj.prototype.get_status = function () {
    return this.status;
};

var myObj = new Obj("going");
myObj.get_status() // "going"


call, apply 메서드

 

다행스럽게도 자바스크립트에는 명시적으로 사용할 컨텍스트를 지정할 수 있는 메서드가 몇 개 있습니다. 아래 예는 이런 일을 하는데 사용할 수 있는 call과 apply 메서드를 보여줍니다.


    // =============================

    //  call 메서드

    // =============================


var  mike = {
    name : 'Mike',

    introduce : function (age, city) {

        alert('my name is ' + this.name + ' and i\'m' + age + ' years old. i live in ' + city);

    }

};

var jane = {

    name : 'Jane'

};

mike.introduce.call(jane, 12, 'seoul');  // "my name is Jane and i'm 12 years old. i live in seoul"


call과 apply 메서드는 특정 함수 내에 this 키워드가 가리키는 객체를 사용자가 지정한 객체로 바꾸어 호출해줍니다. call 메서드의 첫번째 전달 인자는 this 에 바인딩될 객체이고, 나머지 전달인자들은 함수가 호출될 때 함수의 전달인자로 건내집니다.  apply 메서드는 call 과 유사하지만 함수로 건네줄 인자값들을 배열로 지정한다는 점에서 다릅니다.

 

mike.introduce.apply(jane, [12, 'seoul']);



Posted by motolies
,