2011-12-14 16 views
1

私はPostboxアドオンを作成しようとしています(PostboxはThunderbirdに基づくメールクライアントです)、私は小さな問題を抱えています。私はJavascriptの専門家ではなく、この背後にある問題を理解できません。Javascriptオブジェクト関数を正しく拡張するには?

私はPostboxコードからオブジェクト機能を拡張しようとしています。コードはかなり大きいので、問題を実証するための小さな例を作成しようとしました。次のコードは、元の郵便受けコード構造のサンプルです:

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(); 

郵便受けが更新されたときに、私はこのコードの原因を変更することはできません、コードは、元のソースに戻すだろうと、それを維持するために、痛みになります。

次はgetCellProperties機能を拡張しようと、私自身のコードです:今

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を呼び出そうとしたが、それが失敗した元の関数を呼び出しています。

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があります。

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

それとも.callを使用して、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(); 

常に、常に Sに起動されますグローバリゼーションオブジェクトにグローバルオブジェクトを追加します。あなたは、あなたが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]); 
}