2011-12-14 3 views
1

Postbox addon (Postbox는 Thunderbird를 기반으로하는 메일 클라이언트)을 만들려고하는데 작은 문제가 있습니다. 나는 자바 전문가가 아니기 때문에이 문제를 이해할 수 없다 ...Javascript 개체 함수를 올바르게 확장하는 방법은 무엇입니까?

나는 우편함 코드에서 일부 객체 기능을 확장하려고한다. 코드가 상당히 크기 때문에 문제를 설명하기 위해 작은 예제를 만들려고했습니다. 다음 코드는 원래의 우체통 코드 구조의 샘플입니다 : 우체통이 업데이트되는 경우

FolderTreeView.prototype = { 

    init: function FTV__init() { 
     alert("init"); 
    }, 

    _ensureValidRow: function FTV__ensureValidRow(aRow) { 
     alert("_ensureValidRow"); 
    }, 

    getCellProperties: function FTV_getCellProperties(aRow, aColumn, aProperties) { 
     this._ensureValidRow(aRow); 
    } 

} 

function FolderTreeView() { 
    this._tree = null; 
    this.init(); 
} 

var gFolderView = new FolderTreeView(); 

는이 코드의 원인을 변경할 수 없습니다 코드는 원래의 소스로 복귀 것 그리고 그것을 유지하기 위해 통증이있을 것입니다.

MyExtension = { 

    init: function() { 
     MyExtension.FolderIcon.load(); 
    }, 

    FolderIcon: { 
     load: function() { 
      var oGetCellProperties = gFolderView.getCellProperties; 

      gFolderView.getCellProperties = function FTV_getCellProperties(aRow, aColumn, aProperties) { 
       oGetCellProperties(aRow, aColumn, aProperties); 
      } 

      gFolderView.getCellProperties(null, null, null); 
     } 
    } 

} 

지금, oGetCellProperties 차례로 this._ensureValidRow을 호출하려고 원래의 함수를 호출하지만 실패 :

다음은 getCellProperties 기능을 확장하기 위해 노력하고, 내 자신의 코드입니다.

this._ensureValidRow is not a function 

답변

1

a.b()a-b 내부의 this 값을 설정 : 오류 콘솔을보고합니다.

a.b(); // sets `this` value inside `b` to `a` 

var c = a.b; 

c(); // does *not* set `this` value inside `b` to `a` 

을 그래서 당신은 여기서 : 그것을 저장하면하지 않는

var oGetCellProperties = gFolderView.getCellProperties; 
// gFolderView is lost as `this` value 

당신은 오히려 .bind를 원한다. .bind은 최신 브라우저에서만 사용할 수 있지만 이전 브라우저에는 shims이 있습니다. .call 사용

var oGetCellProperties = gFolderView.getCellProperties.bind(gFolderView); 
// force `this` value 

아니면 this 값 당신이 호출 할 때마다 설정할 수 :

//      `this`  argument1, ... 
oGetCellProperties.call(gFolderView, aRow,  aColumn, aProperties); 
+1

이것은 훌륭한 대답입니다. ES5 추가 사항을 좋아하지만 OP는이 표를 확인하여 대상 브라우저가 지원되는지 확인할 수 있습니다. http://kangax.github.com/es5-compat-table/ –

+1

이것은 본질적으로 브라우저에서 실행되지 않으며 Postbox/Thunderbird 확장입니다. 확장에서'bind'와'call' 메소드를 테스트했고 둘 다 잘 작동했습니다 :) –

1

문제의 뿌리는 반대로 기능, 그냥 호출되는 function invocation - 일부 기능을 호출하는 것입니다 ,

someFunction(); 

항상 객체에 항상의 호출되고 et this을 전역 개체에 추가합니다. 당신은 당신이 this이 너무 일하는 것이

gFolderView.getCellProperties = function FTV_getCellProperties(aRow, aColumn, aProperties) { 
     oGetCellProperties.call(gFolderView, aRow, aColumn, aProperties); 
} 

apply에 동일하게 원하는 것을 지정할 수 있습니다 call로 함수를 호출하여이 문제를 얻을 수 있지만, 인수가 배열로 전달 될 것으로 예상되는 당신의 경우 약간 덜 편리합니다.

gFolderView.getCellProperties = function FTV_getCellProperties(aRow, aColumn, aProperties) { 
     oGetCellProperties.apply(gFolderView, [aRow, aColumn, aProperties]); 
} 
관련 문제