2013-07-08 5 views
2

자바 스크립트 코드에 문제가 있습니다.콜백 함수의 가변 범위

나는 MyClass 클래스를 가지고 있으며 프로토 타입에 myFunction 함수를 추가했습니다.

MyClass.prototype.myFunction = function(file){ 
    if(some condition){ 
     fs.exists("./" + file, function(exists){ 
      if(exists) 
       console.log(this.someValue); 
       /* lot of other code */ 
      else 
       /* do something else */ 
    }); 
    }else{ 
     /* do something */ 
    } 
} 

내 문제는 범위 지정 this.someValue입니다 (예로 인쇄하고 싶습니다). 매번 existstrue이고 콘솔은 undefined을 기록하지만 그렇지 않습니다. fs.exists() 외부에서 인쇄하는 경우 값이 있으므로 범위 지정 문제라고 생각합니다.

이 샘플에서 this.someValue에 액세스하려면 어떻게합니까?

미리 감사드립니다.

답변

2

마찬가지로 this - 함수 범위로 정의되고 함수의 소유자 또는 호출자에게 응답하는 키워드입니다. 그래서 당신은 다른 변수에의 포인터를 저장할 수 있습니다 :

MyClass.prototype.myFunction = function(file) { 
    if(some condition) { 
    var self = this; // create variable with pointer to 'this' 
    fs.exists("./" + file, function(exists) { 
     if(exists) { 
     console.log(self.someValue); // we can access it to parent scope variables 
     /* lot of other code */ 
     } else { 
     /* do something else */ 
     } 
    }); 
    } else { 
    /* do something */ 
    } 
} 

뿐만 아니라이 화려한 주제 체크 아웃 : How does the "this" keyword work?

+1

'{위치 : 런던 '}이 (가) 유효하지 않습니다. fwiw – naomik

+0

오타 .. 감사합니다. – moka

3
MyClass.prototype.myFunction = function(file){ 
    var that = this; 
    // some lines of code later... 
     console.log(that.someValue); 
} 
4

당신이 청소기로 다시 작성할 수 있습니다

MyClass.prototype.myFunction = function(file){ 
    if(some condition){ 
     fs.exists("./" + file, function(exists){ 
      if(exists) 
       console.log(this.someValue); 
       /* lot of other code */ 
      else 
       /* do something else */ 
    }.bind(this)); 
    }else{ 
     /* do something */ 
    } 
} 

.bind 내면의 기능

MyClass.prototype.myFunction = function myFunction(file){ 
    if(some condition){ 
    fs.exists("./" + file, this.doSomething.bind(this)); 
    } 
    else{ 
    // do something else 
    } 
} 

MyClass.prototype.doSomething = function doSomething(exists) { 
    if(exists) { 
    console.log(this.someValue); 
    // lot of other code 
    } 
    else { 
    // do something else 
    } 
} 

나는 개인적으로이 솔루션처럼 당신이 우수한 코드 구성을 유지할 수 있기 때문에에있다 function(){ function(){ function(){ ... }}}의 중첩을 방지합니다. 또한 var that = this; 또는 var self = this; 변수가 주위에 떠 다니는 것을 방지하여 어느 범위가 어느 범위인지 궁금하게 만듭니다.

.bind은 느리지 만, minitech가 지적했듯이 파일 액세스에 비해 병목 현상이 발생하지는 않습니다.

+0

바인딩 다른 함수로 범위 포인터를 전달하는 가장 느린 방법 중 하나입니다. 그리고 용도가 약간 다릅니다. – moka

+1

@MaksimsMihejevs : 파일 액세스에 비해 느린가? 마이크로 최적화하지 마십시오 ... – Ryan

+1

파일 작업과 관련이 없지만 단순한 작업에는 속도가 느립니다. 실제로 그것은 극적인 차이점입니다. http://jsperf.com/bind-vs-closure-setup/6 – moka