2012-02-21 1 views
1

이렇게 힘듭니다. 직접 메서드를 호출 할 때 이것은 문자열 변환에서 호출 할 때 "window"를 참조하는 동안 포함 된 객체를 참조합니다 (나는 완전히 틀릴 수 있습니다).자바 스크립트와이 오류. 기능 호출 방법에 따라

아무에게도 설명 할 수 없습니까?

무엇이 일어날 것은

/** 
* converts a string to a function 
*/ 
function stStringToFunction(string) { 
    var fnList = string.split("."); 
    var currentFn = window; 
    var nextFn; 
    while(currentFn !== undefined && (nextFn = fnList.shift())) { 
     currentFn = currentFn[nextFn]; 
    } 
    return currentFn; 
} 

//An example library 
UnderstandingThis.ui.Component1 = { 
    performTask1: function(options) { 
     var settings = { 
       opt1: true, 
       opt2: false 
      }, 
      _this = this; 

     $.extend(settings, options); 

     _this._PrivateTask1(settings); 
    }, 
    _PrivateTask1: function(settings) { 
     //Some sweet stuff here! 
     alert("Private task1: " + settings.from); 
    } 
} 
UnderstandingThis.ui.Component1.performTask1({from: "direct"}); 
stStringToFunction("UnderstandingThis.ui.Component1.performTask1")({from: "string-to-function"}); 

설명 내 부족 편집을 요구

(즉 직접 호출 _this가 정의 된 방법으로 잘 작동을 의미) 첫 번째 경고 문 뒤에 자바 스크립트 오류 : 2/21/2012 오전 9시 56분 (몬태나)

그래서 문제는 가짜 라이브러리 (UnderstandingThis.ui.Component1)가 직접 메타를 할 때 _this를 사용 (this로 설정된)와 잘 작동하는 기능이 포함되어 있다는 것입니다 중독 전화. 그 말은 자바 스크립트에서 UnderstandingThis.ui.Component1.performTask1()을 호출하는 것을 의미합니다. 하지만 문자열 변환을 통해이 동일한 작업을 호출하면 stStringToFunction("UnderstandingThis.ui.Component1.performTask1")()_thiswindow을 나타냅니다. 그러나 나에게 그것은 말이되지 않습니다. 나는 자바 스크립트를 1.5 년 동안 해왔으며이 작은 뉘앙스 (Java/C#에서 제공)는 이해하기 어렵다.

+2

무엇이 문제입니까? –

+2

어떤 오류가 있습니까? 질문에 너무 많은 정의가 없습니다. ** humor ++ ** – gdoron

+0

죄송합니다, 오류를 정의 해주십시오. – Michael

답변

3

귀하의 초기 주장 :

직접 메서드를 호출이 포함하는 객체

을 말한다 정말 사실이 아니다. this 의사 변수는 함수를 가져 오는 데 사용 된 객체 참조에 기반하여 바인딩됩니다 (있는 경우). 어떤 개체의 속성 값으로 함수를 인스턴스화 한 다음 해당 개체 속성을 통해 참조로 호출하면 예, this이 해당 개체에 바인딩됩니다. 그러나이 함수를 값으로 사용하여 속성의 다른 객체를 복사하면 해당 객체를 통한 호출에는 this이라는 객체가 있습니다 (이 주제에 대해 토론 할 때 항상 "처음 사용 하시겠습니까?"). .

어쨌든 .call() 또는 .apply()을 사용하면 기능을 얻는 방법에 관계없이 this 값을 원하는대로 설정할 수 있습니다. 요컨대 JavaScript에서는 함수와 특정 객체간에 고유 한 관계가 없다는 것입니다. this의 바인딩은 모든 함수 호출에서 결정됩니다.

+0

몇 가지 중요한 정보를 제공하셨습니다. 내가 어디 잘못 생각하는지 알아. 당신과 쿠엔틴은 같은 대답을 가지고 있습니다, 당신은 좀 더 일반화되어 있습니다. – Michael

4

당신은 호출하는 경우 :

foo.bar() 

그런 bar 내부 thisfoo입니다.

당신 경우 :

var baz = { bar: foo.bar }; 
baz.bar(); 

그런 다음 bar 내부 thisbaz입니다.

당신은에 있다면 (는 기본 객체이기 때문에)

var bar = foo.bar; 
bar(); 

그런 다음 bar 내부 thiswindow입니다.

이 함수는 해당 컨텍스트에서 함수를 추출한 다음 호출합니다 (thiswindow).

+0

훌륭한 대답이지만 어쩌면이 질문에 "질문 부분"을 얻을 수 없었을 것입니다. – gdoron

+0

이것은 질문에 매우 가깝습니다. 이것은 훌륭한 설명입니다. 내 문자열을 함수 변환은 기본적으로 "bar()"함수 호출을 수행합니다 ... – Michael

+0

내가 너의 것을 받아들이지 않았던 유일한 이유는 너의 것이 매우 실용적인 예 였지만 나를 '이' . 나는 나의 예제에서 내가 어디가 잘못되었는지 이해하지만, @Pointy는'this'가 어떻게 더 깊이 만들어 졌는지 설명했다. 나는 당신에게 표를 던졌고 당신의 대답은 좋았습니다. – Michael

0

문제는 당신이 생각했던 것과 정확히 같습니다. 두 번째 호출에서이 문제는 창을 참조합니다. 여기에 가능한 해결 방법이 있지만 개인적으로 나는 다른 방식으로 일을하고 싶습니다. 피들 여기에 http://jsfiddle.net/LsH7V/

/** 
* converts a string to a function 
*/ 
function stStringToFunction(string) { 
    var fnList = string.split("."); 
    var currentFn = window; 
    var nextFn; 
    while(currentFn !== undefined && (nextFn = fnList.shift())) { 
     currentFn = currentFn[nextFn]; 
    } 
    return currentFn; 
} 

//An example library 
UnderstandingThis = {}; 
UnderstandingThis.ui = {}; 
UnderstandingThis.ui.Component1 = { 

    performTask1: function(options) { 
     var settings = { 
       opt1: true, 
       opt2: false 
      }; 
     if(typeof _this === 'undefined'){  
      _this = this; 
      console.log(this); 
     } 

     $.extend(settings, options); 

     _this._PrivateTask1(settings); 
    }, 
    _PrivateTask1: function(settings) { 
     //Some sweet stuff here! 
     alert("Private task1: " + settings.from); 
    } 
} 
UnderstandingThis.ui.Component1.performTask1({from: "direct"}); 
stStringToFunction("UnderstandingThis.ui.Component1.performTask1")({from: "string-to-function"}); 
+0

당신이 어떻게하는지 나에게 보여 주시겠습니까? 코드는 코드이며, 일을하는 "올바른"방법은 없습니다. (나는 진절머리가 나는 코드를 정당화하지는 않지만 좋은 코드는 여러 가지 방법으로 수행 할 수있다) – Michael