2017-08-12 1 views
1

に私が間違っているかもしれないが、私の理解は、私は矢印の関数としてfoo.bazを定義しないように注意をしたので、以来、この「この」(矢印ではない)関数内で定義されていないオブジェクト

var foo = {                                       
    'bar': x => x + 1,                                     
    'baz': function(y){ return this.bar(y); }                               
};                                          

foo.baz(1); 

が正常に動作する必要がありますということですthis内はbazfooと等しい。もちろん、私はそれが期待どおりに動作するコンソール上でテストします。

ここでは、何らかの理由でthisが未定義になるReactでのセットアップが非常に似ています。これはコードです:

const MapRoom = {                                      
    'getStyleFromCoords': coords => {                                 
     return { // account for borders                                
      'left': coords[0] + 1,                                
      'top': coords[1] + 1,                                
      'width': (coords[2] - coords[0]) - 2,                           
      'height':(props.coords[3] - props.coords[1]) - 2,                           
     };                                        
    },                                         
    'Disabled': function(props){                                  
     console.log('this', this); // undefined                                  
     const style = this.getStyleFromCoords(props.coords); // error                           

     return (                                      
      <div                                      
       className="room-selected"                                
       style={style}                                   
       title={props.number}                                  
       ></div>                                     
     );                                        
    } 
} 

、その後

renderRooms(){                                       
    // stuff                        

    return this.state.coords.map((coords, index) => {                             
     // more stuff 
     if(disabled){                                         
      return (                                          
       <MapRoom.Disabled                                       
        key={roomNumber}                                  
        number={roomNumber}                                      
        coords={coords}                                  
        />                                     
      );                                       
     } else if(...){} 
    }); 
} 

render(){ 
    return (
     <stuff> 
      {this.renderRooms()} 
     </stuff> 
    ); 
}                                                                    

私は、彼らがanalagousあるべきだと思いますが、それはケースではありませんようです。もちろん、私はオブジェクトの外に関数を移動することができますし、thisを参照する必要はありませんが、エラーを再現できないため実際に何が起こっているのか不思議です。

ケースでは、私がバベルでコードをtranspilingだし、出力が

var MapRoom = {                                      
    'getStyleFromCoords': function getStyleFromCoords(coords) {                          
     return { // account for borders                                
      'left': coords[0] + 1,                                
      'top': coords[1] + 1,                                
      'width': coords[2] - coords[0] - 2,                           
      'height': coords[3] - coords[1] - 2                           
     };                                        
    },                                         
    'Disabled': function Disabled(props) {                                
     console.log('this', this);                                  
     var style = this.getStyleFromCoords(props.coords);                             

     return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement('div', {                     
      className: 'room-selected',                                
      style: style,                                    
      title: props.number                                  
     });                                       
    } 
} 

これはWebPACKのコンパイラによって作成された匿名関数内である、問題になります。

+2

あなたはあなたがfoo.baz' '呼んでいたが、' MapRoomを何を呼び出しているではないか私達に示したよりも違いはありません.Disabled'。通常の 'function'を使用する場合、関数が定義されている場所ではなく' this'を設定する_called_をどのように使用しているのかを知ることができます。 – loganfsmyth

+0

@loganfsmythあなたは完全に正しいです、私の悪いです。それが今であれば教えてください。 – cronos2

+0

コンパイル結果に 'this'は使用されません。 – melpomene

答えて

1

通常のfunctionの値は、関数の呼び出し方法に基づいて設定されます。オブジェクトがどのように宣言されているかの構造は何の効果もありません。foo.baz(1);thisからfooに設定されています。それを打破するには

foo.baz(1); 

は、この場合には_tmpはかなりちょうどfooを使用する代わりにスキップすることができ

let _tmp = foo; 
_tmp.baz.call(_tmp, 1); 

に相当します。あなたのJSXの場合

<MapRoom.Disabled /> 

は、その関数がちょうど機能、例えばを取得

declareComponent(MapRoom.Disabled); 

をやっています関数が呼び出される時まで

function declareComponent(someFunc){ 
    someFunc(); 
} 

は、それだけの機能ですが、何のobj.someFuncは、それがundefinedされて終わるのでthisは、objする原因となることもありません。

明確にするために、関数がオブジェクトのプロパティとして宣言されているという事実は何にも影響しません。それは単なる関数であり、関数が適切なthisの値で確実に呼び出されることはあなた次第ですもしあなたが一定の期待を持っていれば。例えば、あなたが行うことができる

const MapRoomDisabled = MapRoom.Disabled.bind(MapRoom); 

<MapRoomDisabled /> 

この関数は明示的なコンテキストでバインドされているので、期待どおりに動作します。

しかし

var obj = { 
    prop: function(){} 
}; 

var obj = { 
    prop: null 
}; 
obj.prop = function(){}; 

または

var someFunc = function someFunc(){} 

var obj = { 
    prop: someFunc, 
}; 
関連する問題