2017-08-12 17 views
1

我可能是错的内部功能(不是箭头)是不明确的,但我的理解是,这“这”在对象

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

foo.baz(1); 

应该可以正常工作,因为我照顾不来定义foo.baz如箭功能等this内部baz等于foo。当然,当我在控制台上测试它时,它会按我的预期工作。

现在,我有一个非常类似的设置与React,其中this由于某种原因未定义。这是代码:

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中的this值是根据函数的调用方式设置的。对象声明的结构没有任何影响,只是foo.baz(1);设置了thisfoo

要打破它,

foo.baz(1); 

相当于

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

其中在这种情况下,_tmp可能是非常到位只是用foo的跳过。

在您的JSX情况下

<MapRoom.Disabled /> 

declareComponent(MapRoom.Disabled); 

如该函数只是得到的功能,例如

function declareComponent(someFunc){ 
    someFunc(); 
} 

该函数被调用的时候,它只是一个功能,没有obj.someFunc会导致thisobj,所以它最终被undefined

为了阐明,事实上你的函数被声明为一个对象的属性对任何东西都没有影响,它仍然只是一个函数,它是由你来确保函数被调用正确的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, 
};