2010-02-15 4 views
20

는이 코드가 있습니다액세스 외부 "이"자바 스크립트 정렬 방법

function some_object(...) { 
    this.data = {...}; 

    this.do_something = function(...) { 
     var arr = [...]; 

     arr.sort(function (a, b) { 
     return this.data[a] - this.data[b]; 
     }); 
    } 
} 

thissort에 액세스 할 수 없기 때문에 내 생각은 작동하지 않습니다하지만 - 다른 this 어떤 이유로 아닌 this 거기에 볼을 외부 물체를 감싸는 것.

어떻게해야합니까? 덕분에

답변

29

다른 thisarr.sort이라는 익명 함수 (자체 폐쇄)가 this이 주 개체와 다른 항목으로 설정된 함수를 호출하기 때문입니다. Array.sort에서 실제로 무엇을 this으로 설정했는지는 확실하지 않지만 아마 정렬 할 배열 일 것입니다. 당신의 정렬 알고리즘 (배열에 의해 제공되는 것 이외의) do_something 내에서 아무것도에 의존하지 않기 때문에

function some_object(...) { 
    var so = this; // so = current `this` 
    this.data = {...}; 

    this.do_something = function(...) { 
     var arr = [...]; 

     arr.sort(function (a, b) { 
     return so.data[a] - so.data[b]; 
     }); 
    } 
} 
+5

감사하지만,이 자바 스크립트에서 허용 방법? 솔직히 못생긴 해킹처럼 보입니다 :-) – zaharpopov

+0

왜 "do_something"이 클로저를 만드는 걸까요? do_somethiing에서'this'를 출력하면 올바른 객체를 얻을 수 있습니다. – zaharpopov

+2

아니요, 해킹이 아닙니다. 다른 방법은 'this'가 함수에 바인딩되어 있다는 것을 구체적으로 설정하는 것입니다. 그러나,이 경우,'arr.sort' 메쏘드는 호출을하고,'this'가 무엇을 의미하는지 설정할 기회가 없습니다. 시나리오와 같은 객체에서, 나는 실제로'var base = this; '를 맨 위에 선언하고 함수의 범위 내에서 그 객체를 참조하기 위해서만'base'를 사용합니다. 그렇게하면'this'와'base'를 언제 사용해야하는지 추측 할 필요가 없습니다. –

0

, do_something 외부의 기능을 이동하는 것을 고려 :이 상황에서 주위의 정상 작동은 다른 변수를 사용하는 것입니다 :

function some_object(...) { 
    var so = this; 
    so.data = {...}; 
    var comparator = function(a,b) { return so.data[a] - so.data[b]; }; 

    this.do_something = function(...) { 
     var arr = [...].sort(comparator); 
    } 
} 

아니면 다른 곳에 정렬 이런 종류의 할 경우, 심지어 간단한 공장을 제공합니다

var comparatorFactory = function(data) { return function(a,b) { return data[a] - data[b]; } }; 
function some_object(...) { 
    var so = this; 
    so.data = {...}; 
    var comparator = comparatorFactory(so.data); 
    ... 
1

당신은 빈을 할 수 있습니다 내부 함수에 대해 bind 메서드를 호출하여 "외부"인스턴스를 "내부"함수에 추가합니다. MDN에서 자세히 알아보십시오.

예 : https://jsfiddle.net/eheobo/twv3emh7/1/

var foo = { 
    data: [1, 2, 3, 4], 
    bar: function() { 
     var printData = function(){ 
      this.data.forEach(a => console.info(a)) 
     }.bind(this) 
     printData() 
    } 
} 

foo.bar()