var test = this;
var ltTest = {
    _ltTest : this,
    init : function(){
        return this;
    }
}

위와 같은 javascript를 짰습니다. 그리고 다음을 찍어보면...

ltTest          // 1
ltTest.init()       // 2
ltTest._ltTest      // 3
test            // 4

1,2 번은 ltTest가 떨어지는데, 3,4는 DOMWindow가 떨어집니다. 그래서

ltTest === ltTest._ltTest   // false

ltTest._ltTest가 왜 DOMWindows 죠? ltTest여야 하는거 아닌가요?

asked Feb 11 '11 at 10:44

zziuni's gravatar image

zziuni
556

edited Feb 11 '11 at 10:54


Javascript 는 function scope 만 지원합니다.. { } 안에 들어있다고 this 가 가리키는 context 가 바뀌지 않습니다..

즉, Global Scope 에서의 this 가 object window 를 가리키는것을 제외하고는..

언제나 this 는 function 내에서 실행시점의 해당 function 의 소유자(Context) 를 가리킵니다.

따라서 ltTest 라는 객체의 property 로 this 를 넘긴다고 해서 ltTest 가 지정되는것이 아닌, _ltTest 가 생성되는 시점에서의 this 는 object window 를 가리키게 됩니다.

answered Feb 11 '11 at 12:10

boxersb's gravatar image

boxersb
956

완전히 이해하셨다는 것은 개념적인 이해이고, 암기적인 이해입니다. ㅋㅋㅋ 저도 첨삭을 하자면

자바스크립트는 실행 시점(Runtime Point) 가 굉장히 중요한 언어입니다. 우리는 브라우저에서 웹페이지가 로드되고 자바스크립트를 인터프리터에 의해서 해석되어지는데 이때 위에서 언급한 리터럴이라는 녀석은 ECMA 스펙에서 모두 동일하게 정의하고 있습니다.

모든 리터럴은 Constructor 를 수행는 절차를 갖는다. (이런 문장으로 정의 되어있는 것은 아닌 리터럴 부분을 보면 수행 절차중에 컨스트럭터를 호출하는 존재합니다.)

예를 들어


var a1 = {};
var a2 = {};
...
...
var a999999 = {};

모두 function Object() { [native code] } 라는 생성자를 호출하여 오브젝트 인스턴트로 만듭니다.

위의 내용을 전제하에 기재해주신 예시 var ltTest = { ... } 는 @boxersb 가 의미와 결과는 동일하나 저는 약간 다르게 설명해봅니다.

itTest 라는 { ... } 오브젝트가 생성되는 시점에서 var itTest = new Object({ ... }); 형태로 정의하신 { _itTest : this, init : function() { return this } } 는 function Object() { [native code } 의 인자로 전달되게 됩니다.

즉 var itTest = new Object( { _itTest : this, init : function() { return this; } } ); 와도 같게 됩니다. 즉 리터럴이 생성되는 시점에서의 this 의 Scope와 init 가 호출되어 this 를 리턴하는 시점은 다릅니다.

만약


var itTest = { _itTest : a, init : function() { return this; } } ); 

이 시점에서 a 라는 변수가 정의되지 않았다면 ReferenceError 이 발생하겠죠.

하지만


var a = 'frends';
var itTest = { _itTest : a, init : function() { return this; } } );

라고 되어있다면 이야기는 달라집니다.

기재해주신 코드를 명확히 이해하기 위해서는 Scope 의 개념도 중요하고 실행 시점을 명확히 이해하는 것도 중요합니다.

answered Feb 11 '11 at 23:35

Rhiokim's gravatar image

Rhiokim
336

reverted Feb 11 '11 at 23:52

{ } Object literal 의 생성자를 호출하는 것에 대한 정의는 ECMA-262 3rd page.42 에 다음과 같이 정의되어 있습니다.

The production ObjectLiteral : { } is evaluated as follows:

  1. Create a new object as if by the expression new Object().
  2. Return Result(1).
(Feb 11 '11 at 23:55) Rhiokim

var test = this; 이 라인이 Global Scope 시점이기 때문에 this 는 Global 객체인 Object Window 를 가리킵니다. ltTest 객체의 _ltTest property 에 this 를 대입할때도 대입하는 시점 자체가 가리키는 this 는 Object WIndow 입니다. 2 - ltTest.init() 에서는 함수 내부에서의 컨텍스트를 따릅니다. init 함수 내부에서 가리키는 this 는 그 함수를 소유하고 있는 객체.. 즉 ltTest 가 됩니다..

따라서 test, ltTest._ltTest 와 init 내부에서의 this 는 다릅니다. :)

꼭 _ltTest 에 ltTest 를 할당하려면 객체 선언이 끝난 후에 할당해야 합니다.

var ltTest = {
    _ltTest : null,
    init : function(){
        return this;
    }
};
ltTest._ltTest = ltTest;

answered Feb 11 '11 at 11:02

boxersb's gravatar image

boxersb
956

edited Feb 11 '11 at 11:08

  1. 변수의 생성시기를 착각하고 있는 것이예요. var ltTest statement가 JS 엔진에 의해 compile 될 때 _ltTest: this 의 this는 이미 window를 가지고 있어요.

  2. this는 생성당시에 결정되는 것이 아니라, 호출 당시에 결정되지만 ltTest._ltTest는 함수호출이 아니라 속성 참조일뿐이예요.

answered Feb 11 '11 at 11:12

andrwj's gravatar image

andrwj
1093

제 질문의 요점은. literal 안에서 그러니까 {~~~} 란 scope 안에서의 this는 다 같은게 아니냐.. 였습니다.

boxersb 설명처럼, 함수 안에서의 this가 소유한 객체를 의미하는거라면..

literal로 정의된 {.... } 이 객체인거고..

그러면 객체안에서의 this(_ltTest) 도 그 객체여야 하는게 아니냐...는

생각이였거든요.

생성과 실행시기를 혼동하는것 같은데 정리좀 해봐야겠군요.

answered Feb 11 '11 at 11:35

zziuni's gravatar image

zziuni
556

  1. {.. } 은 literal 이 아니라 block 입니다.
  2. 굳세게 믿고 있는 것과 달리, block 안은 scope가 없습니다. Java가 아니라 Javascript 니까요 :-)
  3. var ltTest = {.. } 코드는 object assign statement 입니다. 즉, 스크립트가 JS engine에 의해서 바로 컴파일 되는 부분이라는 거죠. init() 함수안의 코드는 함수진입 당시에 처리됩니다.
(Feb 11 '11 at 13:14) andrwj

음.. 딴지는 아니지만, 특별한 구문을 제외하고 변수에 { ... } 으로 할당하는것도 Object literal 로 부를 수는 있습니다.. [] 는 배열 리터럴, "" 는 스트링 리터럴, 심지어 function(){ ... } 는 함수 리터럴로 볼 수 있습니다.. Javascript 는 Functional Language 이기 때문에 이 리터럴들의 원형은 모든 new SOMETHING(); 식이 되는것으로 알고 있습니다..

(Feb 11 '11 at 18:05) boxersb

멋진 지적 :-) 리터럴에 대한 글을 쓰고 다시 예기합시다,,, 재밌네; ㅋ (이거 우리끼리 노는건가?)

(Feb 11 '11 at 23:04) andrwj

예 저도 리터럴도 알고 있습니다. 저런코드가 마치 JSON처럼 보이지만 보통은 JavaScript Literal방식이라고 부르더군요. 전 클래스보다는 이런 형태가 더 좋던데요 ㅎ

(Feb 11 '11 at 23:41) Outsider

아하~ 평션스코프!!

answered Feb 11 '11 at 12:19

Outsider's gravatar image

Outsider
1186

아.. 이제 완전히(?) 이해했습니다. Scope 에 대한 정의가 틀렸었군요. 감사~

answered Feb 11 '11 at 16:12

zziuni's gravatar image

zziuni
556

내 답변
toggle preview

구독:

로그인 후에는 모든 변경사항에 대해 구독할 수 있습니다.

Tags:

×7

질문등록: Feb 11 '11 at 10:44

열람: 1,518 times

최종 수정: Feb 11 '11 at 23:55

powered by OSQA