cro*_*os2 6 javascript scope this undefined babeljs
我可能是错的,但我的理解是
var foo = {
'bar': x => x + 1,
'baz': function(y){ return this.bar(y); }
};
foo.baz(1);
Run Code Online (Sandbox Code Playgroud)
应该可以正常工作,因为我注意不要定义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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
进而
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>
);
}
Run Code Online (Sandbox Code Playgroud)
我会说它们应该是类似的,但似乎并非如此。当然,这不是什么大问题,因为我可以将函数移到对象之外,然后不需要this引用它,但是我很想知道实际发生了什么,因为我无法重现错误。
万一重要,我正在用 Babel 转译代码,输出是
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
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是在 WebPack 编译器创建的匿名函数中。
this法线中的值是function根据函数的调用方式设置的。对象的声明方式的结构没有影响,只是foo.baz(1);设置this为foo。
为了打破它,
foo.baz(1);
Run Code Online (Sandbox Code Playgroud)
相当于
let _tmp = foo;
_tmp.baz.call(_tmp, 1);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,_tmp几乎可以跳过 来代替仅使用foo.
在你的 JSX 案例中
<MapRoom.Disabled />
Run Code Online (Sandbox Code Playgroud)
是在做
declareComponent(MapRoom.Disabled);
Run Code Online (Sandbox Code Playgroud)
该函数只是获取函数的地方,例如
function declareComponent(someFunc){
someFunc();
}
Run Code Online (Sandbox Code Playgroud)
当函数被调用时,它只是一个函数,没有任何obj.someFunc东西会导致this成为obj,所以它最终成为undefined。
this需要澄清的是,您的函数被声明为对象的属性这一事实对任何事情都没有影响,它仍然只是一个函数,如果您有一定的值,则由您来确保使用正确的值调用该函数期望。例如你可以这样做
const MapRoomDisabled = MapRoom.Disabled.bind(MapRoom);
<MapRoomDisabled />
Run Code Online (Sandbox Code Playgroud)
由于该函数已与显式上下文绑定,因此它将按您的预期工作。
但
var obj = {
prop: function(){}
};
Run Code Online (Sandbox Code Playgroud)
与
var obj = {
prop: null
};
obj.prop = function(){};
Run Code Online (Sandbox Code Playgroud)
或者
var someFunc = function someFunc(){}
var obj = {
prop: someFunc,
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2953 次 |
| 最近记录: |