Javascript ES6中嵌套类的上下文很奇怪
我有以下嵌套类结构:Javascript ES6中嵌套类的上下文很奇怪,javascript,reactjs,firefox,webpack,Javascript,Reactjs,Firefox,Webpack,我有以下嵌套类结构: import React, {Component} from 'react'; import {TextField} from '@material-ui/core'; import './ProfileEditor.css'; export default class ProfileEditor extends Component { SyncedTextField = class SyncedTextField extends Component {
import React, {Component} from 'react';
import {TextField} from '@material-ui/core';
import './ProfileEditor.css';
export default class ProfileEditor extends Component {
SyncedTextField = class SyncedTextField extends Component {
onChange = event => {
console.log(this);
};
render() {
return (
<TextField
{...this.props}
onChange={this.onChange}/>
);
}
};
render() {
return (
<form className={"ProfileEditor"}>
<this.SyncedTextField/>
</form>
);
}
}
import React,{Component}来自'React';
从“@material ui/core”导入{TextField};
导入“/ProfileEditor.css”;
导出默认类ProfileEditor扩展组件{
SyncedTextField=类SyncedTextField扩展组件{
onChange=事件=>{
console.log(this);
};
render(){
返回(
);
}
};
render(){
返回(
);
}
}
当代码被Webpack绑定并在Firefox中运行时,它会正确地运行this.onChange
,但输出的this
引用了ProfileEditor
类的上下文
这太奇怪了,因为在JSX中,当我引用“This”时,它正确地指向SyncedTextField,但在onChange方法中,它指向ProfileEditor
我确实在ProfileEditor
中添加了一些属性来检查我自己的健康状况,这些属性显示为ProfileEditor
中声明的属性,即使在SyncedTextField中提供了冲突的定义
有人能告诉我如何避免这个问题吗?是什么导致了这个问题?浏览器开发工具可能会出现不正确的行为。但在这种情况下,这是由transpiler的工作方式引起的。Babel 6类字段(第3阶段建议)转换实现中存在错误 在
onChange
中,使用Babel输出ProfileEditor
作为this
进行编译
下面是来自Babel输出的SyncedTextField
构造函数:
function SyncedTextField() {
var _ref2;
var _temp2, _this2, _ret2;
_classCallCheck(this, SyncedTextField);
for (
var _len2 = arguments.length, args = Array(_len2), _key2 = 0;
_key2 < _len2;
_key2++
) {
args[_key2] = arguments[_key2];
}
return (
(_ret2 = ((_temp2 = ((_this2 = _possibleConstructorReturn(
this,
(_ref2 =
SyncedTextField.__proto__ ||
Object.getPrototypeOf(SyncedTextField)).call.apply(
_ref2,
[this].concat(args)
)
)),
_this2)),
(_this2.onChange = function(event) {
console.log(_this); // SHOULD BE _this2
}),
_temp2)),
_possibleConstructorReturn(_this2, _ret2)
);
}
当输入时,它输出SyncedTextField
使用TypeScript编译(默认情况下由Stackblitz在React模板中使用)按预期工作,并在onChange
中将SyncedTextField
输出为this
由于类很少以这种方式定义,巴别塔bug通常不适用。
SyncedTextField=class-SyncedTextField扩展组件{…}
是反模式。没有理由这样嵌套类表达式。它的效率很低,因为它是在每个ProfileEditor
实例化上进行计算的。它应该是类声明,这样可以用作。
即使出于可测试性或可扩展性的原因,SyncedTextField
应定义为ProfileEditor
组件的属性,最好将其设为prototype属性:
class SyncedTextField extends Component {...}
class ProfileEditor extends Component {
get SyncedTextField() { return SyncedTextField }
...
}
不正确的行为可能特定于浏览器开发工具。但在这种情况下,这是由transpiler的工作方式引起的。Babel 6类字段(第3阶段建议)转换实现中存在错误 在
onChange
中,使用Babel输出ProfileEditor
作为this
进行编译
下面是来自Babel输出的SyncedTextField
构造函数:
function SyncedTextField() {
var _ref2;
var _temp2, _this2, _ret2;
_classCallCheck(this, SyncedTextField);
for (
var _len2 = arguments.length, args = Array(_len2), _key2 = 0;
_key2 < _len2;
_key2++
) {
args[_key2] = arguments[_key2];
}
return (
(_ret2 = ((_temp2 = ((_this2 = _possibleConstructorReturn(
this,
(_ref2 =
SyncedTextField.__proto__ ||
Object.getPrototypeOf(SyncedTextField)).call.apply(
_ref2,
[this].concat(args)
)
)),
_this2)),
(_this2.onChange = function(event) {
console.log(_this); // SHOULD BE _this2
}),
_temp2)),
_possibleConstructorReturn(_this2, _ret2)
);
}
当输入时,它输出SyncedTextField
使用TypeScript编译(默认情况下由Stackblitz在React模板中使用)按预期工作,并在onChange
中将SyncedTextField
输出为this
由于类很少以这种方式定义,巴别塔bug通常不适用。
SyncedTextField=class-SyncedTextField扩展组件{…}
是反模式。没有理由这样嵌套类表达式。它的效率很低,因为它是在每个ProfileEditor
实例化上进行计算的。它应该是类声明,这样可以用作。
即使出于可测试性或可扩展性的原因,SyncedTextField
应定义为ProfileEditor
组件的属性,最好将其设为prototype属性:
class SyncedTextField extends Component {...}
class ProfileEditor extends Component {
get SyncedTextField() { return SyncedTextField }
...
}
在Microsoft Edge中测试时也会发生同样的情况。是的,没错,因为它是一个箭头函数。。。其
此
与函数是常规表示法(即您如何呈现()
)不同哦,因此箭头函数将保持绑定到ProfileEditor
范围,而不是SyncedTextField
?我觉得有点奇怪,但是谢谢!这与定义函数时这个是什么有关,或者其他什么-我在解释箭头函数时很糟糕:p有什么原因不能一次更改(事件)吗{
…等等?不,没有,我只是在试验上下文是什么,结果真的让我吃惊。我想这可能是因为类
在内部是一种提供带有原型的函数的更奇特的方式,我在登录时看到了这一点。在Microsoft Edge中测试时也会发生同样的事情。是的,这是正确的,因为这是一个arrow函数…它的此
与函数是常规符号时的情况不同(即,您是如何呈现()的
)哦,所以箭头函数将保持绑定到ProfileEditor
范围,而不是SyncedTextField
?对我来说似乎有点奇怪,但是谢谢!这与定义函数时这个
是什么有关-我很难解释箭头函数:p有什么原因不能一次更改吗(活动){
…等等?不,没有,我只是在试验上下文是什么,结果真的让我吃惊。我想这可能是因为类
在内部是一种更为奇特的方式来提供一个带有原型的函数,我在登录时看到了这一点。答案令人惊讶。Create React应用程序会自动添加Babel吗?作为旁注,我不想提取SyncedTextField,因为它管理了ProfileEditor
的状态。create-react-app只是用于设置Webpack+Babel模板的CLI工具。因此,是的,它使用了Babel。我希望这个问题在Babel 7中得到修复,这样你就可以弹出项目并将Babel升级到7。因为它管理了Profil