2011-02-17 3 views
0

이 내가 여기자바 스크립트 클로저 문제가 다시 발생합니다.

 
function AAA(){ 
    this.f1 = function(){ 
     /*expecting that f2 will be call as both of then are of same object.*/ 
     console.log(f3(5));// 
    } 

    /*naming the function f3 hope to get function reference, as function 
    on the right side has name now and in the closure of f1, right?*/ 
    this.f2 = function f3(x){ 
     return x; 
    } 

    function f4() {}; 
} 

x = new AAA(); 
x.f1(); //ReferenceError: f3 is not defined 

을 무슨 일이 벌어지고,

 
function AAA(){ 
    this.f1 = function(){ 
     /*expecting that f2 will be call as both of then are of same object.*/ 
     console.log(f2(5));// 
    } 

    this.f2 = function(x){ 
     return x; 
    } 
} 

x = new AAA(); 
x.f1(); //ReferenceError: f2 is not defined 

어느 작동합니까에 직면하고 무엇인가? 누가 'f4'를 제외하고 'f1'을 닫았습니까? 'this'없이는 같은 객체 함수를 호출 할 수 없습니까?

답변

1

this.f2()이 아니어야합니다. f2() 그 자체입니다. f2()은 개인 변수 인 경우 var 키워드로 작성된 경우를 의미합니다.

function AAA(){ 
    var f3 = function(x) { return x; }; 
    this.f1 = function(){ 
     /*expecting that f2 will be call as both of then are of same object.*/ 
     console.log(this.f2(5));// 
     console.log(f3(10)); 
    } 

    this.f2 = function(x){ 
     return x; 
    } 
} 

DEMO

+0

: this.f2'라는 이름의 변수를 생성하지 않습니다'f2''에 할당하지만, 코드 당신이 당신의 코드가 작동하려면, 당신은 단지 이것에 대한 참조가 필요 'f2'라는 변수 (!)에 접근하려고 시도합니다. –

+0

@Chistopher 함수 이름을 f3으로 할 때 두 번째 예제가 어떻게됩니까? – Zer001

3

당신은 정말 여기 클로저를 사용하고 있지 않습니다. 당신이 클로저를 사용하려는 경우

console.log(this.f2(5)); 

에 라인을 변경하는 경우는 다음과 같이 클래스를 다시 작성할 수 있습니다, 잘 작동합니다 : 당신은 여기에 몇 가지를 혼동하고

function AAA() 
{ 
    var f1 = function() 
    { 
     console.log(f2(5)); 
    }; 

    // f2 is a private function. 
    var f2 = function(x) 
    { 
     return x; 
    }; 

    // Define the public interface. 
    return { f1: f1 }; 
} 
+0

예, 당신의 요지를 가지고 있지만, 누가 f1을 닫았는지 궁금하거나, 왜 우리가 'this'없이 같은 대상 기능을 호출 할 수 없습니까? 메커니즘은 무엇입니까? – Zer001

+0

@ abdullah829 : 동일한 객체의 다른 멤버를 참조하는 경우 다른 언어에서는 "this"를 생략 할 수 있습니다. 당신은 자바 스크립트에서 그렇게 할 수 없습니다. "f2"를 작성하고 "this"를 생략하면 자바 스크립트는이 이름을 가진 지역 변수를 찾고 범위 체인 (클로저)으로 올라가고 마침내 전역 범위 (윈도우 객체)를 보게 될 것입니다. . –

+0

괜찮습니다! 그런 다음, 두 번째 예제와 같은 함수의 이름을 지정하면 어떻게됩니까? 이름이 f3 인 경우 this.f2에 할당하지 않으면 제대로 작동합니까? 권리 – Zer001

2

; this과 클로저는 완전히 다른 두 가지 문제입니다.

f2을 직접 참조하려고합니다. 즉, this이 현재 실행 범위의 일부라고 가정합니다. 이 아닙니다.
f2this에 입력하면 this.f2으로 계속 참조해야합니다. f2을 직접 참조하려면 해당 이름으로 (별도의) 변수를 선언해야합니다. 그러면 원하는 경우 this에 할당 할 수 있습니다. qwertymk에는 다음과 같이 표시됩니다. 그 의미는 함수가 호출되는 방식에 완전히 의존하기 때문에

개인적으로, 나는 내가 할 수있는만큼 this을 피하려고 (AAAnew 연산자를 지정하지 않고 호출되는 경우 예를 들어, this는 전역 객체를 참조 할 것!) . 또한 위와 같은 두통으로부터 당신을 구해줍니다. 클로저 (Elian에 의해 입증 됨)는이 기능을 얻는 훨씬 더 좋은 방법입니다.
흥미롭게도 나는 거의 찾지 못했습니다. this을 사용해야합니다. AAA의 기능이 실행 완료되면, 아무도 AAA 내에 정의 (여전히 액세스 할 수 있습니다) 된 기능을 제외하고, F2를 액세스 할 수 없습니다 : 이었다는의 예에서

, f2 닫혀있다. 이 경우 반환 된 객체에서 f1 함수에 액세스 할 수 있으므로 여전히 존재합니다. 따라서 f1은 여전히 ​​ f2을 사용할 수 있습니다.
그 이유는 클로저에 관한 것입니다. 함수는 해당 변수가 종료 된 함수에서 선언 된 경우에도 해당 범위의 모든 변수에 계속 액세스 할 수 있습니다.

0

다른 사람들은 이미 문제가 무엇인지 말해 주었기 때문에 나는 그것을 반복하지 않을 것입니다.언급 정확히 이유 qwertymk를 들어

function AAA(){ 
    var self = this; 
    this.f1 = function(){ 
     console.log(self.f2(5)); //self.f2 exists, yay 
    } 

    this.f2 = function(x){ 
     return x; 
    } 
} 

x = new AAA(); 
x.f1(); //5 
관련 문제