Javascript ES6 消除了在 类 中到处使用 'this' 关键字
Javascript ES6 eliminate usage of 'this' keyword everywhere in classes
我现在正在使用 Traceur 来写一些 javascript 的未来,这是我在一些 class
中拥有的功能
create() {
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.segmentcache = new SegmentCache(this.game);
this.segments = new Segments(this.game);
this.segments.cache = this.segmentcache;
this.segments.seek(3);
this.guy = new Guy(this.game, 140 + 8, 80);
this.guy.anchor.set(0.5, 1.0);
this.game.add.existing(this.guy);
this.game.camera.x = 100;
this.ticks = 0;
this.cross = 0;
}
当然,与任何传统的 javascript 代码一样,它到处都覆盖着 this 关键字。来自 Java 之类的,当我不需要指定 class 中的字段时,我必须指定它是非常不自然的。
是否有任何方法可以让 Traceur 以与 Java 相同的方式解释 classes? (即未指定时自动插入,等等)
据我所知,不。
在Java、C#、C++等中这是编译器的特性,不是执行。这意味着它是隐式完成的,编译器所做的是将正确的地址放入 this
并以正确的方式引用变量。大多数编译器都有一个规则,如果你有一个同名的局部变量(在局部范围内),它具有成员变量的优先级。
虽然在 javascript 中,您可以通过 call
、apply
或 bind
轻松替换 this
,并让您的函数被调用 over 作者不打算使用的对象(即 this
可能是具有不同结构的对象)。我认为这就是为什么语言语法要求您始终明确指定您是指范围还是 this
.
的原因
更多 javascript 函数体实际上可以读取全局范围,因此定义 window.member
(如果在浏览器中)可能会改变函数的行为,如果您不使用显式 this
据我所知,ES6中没有这个功能
由于 Java脚本允许在父作用域中引用变量,因此这种类型的功能会变得复杂。因此,它必须以某种方式辨别一行代码是否像:
ticks = 0;
表示
this.ticks = 0;
或者是否表示通过名称ticks
引用当前或父作用域中的变量。
仅向对象添加 属性 可能会在 属性 引用与局部变量或一样的名字。那很可能会一团糟。现在,您必须为局部变量命名范围,以避免与 属性 名称发生冲突。而且,如果您必须限定局部变量的范围,那么您只是重新引入了一段您试图摆脱的额外语法。
Java 可以容忍这一点,因为编译器预先知道所有 属性 名称,因此如果存在冲突它可以报告错误。 Java脚本允许动态添加属性(随时添加),因此解析器实际上不知道在解析时什么 属性 名称会或不会出现在任何给定对象上,因此它不会发出警告关于冲突。这只是语言 parse/compile 和工作方式的内在差异,因此导致在表达代码时存在一些不同的功能或要求。
可以使用 with
结构来避免一些输入,但是 with
正在从 Java 脚本中删除(在严格模式下不允许),原因详述 here,没有增强,所以不是推荐的方法。
如果你想避免在构造函数中(或任何地方)分配实例变量时必须键入 this
,你可以使用 _.extend()
// this, this, this
this.a = true;
this.b = 2;
this.c = "three";
// becomes...
_.extend(this, {
a: true,
b: 2,
c: "three"
});
作为可能的简单说明,您可以预处理 classes 以插入 this.
用于一组预定义的 属性 名称,例如通过每个 class 的自定义静态元配置,可用于 gulp
构建文件。
DEBUG ClassPreprocessor: buildSync [ 'logger',
'context',
'config',
'startedComponents',
'components',
'requiredComponents' ]
regex ([^a-z\.'])(logger|context|config|startedComponents|components|requiredComponents)([^a-z:'])
replaceWith this.
从指定的道具名称开始,现在我正在构建一个正则表达式来预处理 class。但是,这非常脆弱,因为它不是基于令牌的。稍后,我想通过 AST 上的 Babel 转换器尝试类似的东西。
我现在正在使用 Traceur 来写一些 javascript 的未来,这是我在一些 class
中拥有的功能create() {
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.segmentcache = new SegmentCache(this.game);
this.segments = new Segments(this.game);
this.segments.cache = this.segmentcache;
this.segments.seek(3);
this.guy = new Guy(this.game, 140 + 8, 80);
this.guy.anchor.set(0.5, 1.0);
this.game.add.existing(this.guy);
this.game.camera.x = 100;
this.ticks = 0;
this.cross = 0;
}
当然,与任何传统的 javascript 代码一样,它到处都覆盖着 this 关键字。来自 Java 之类的,当我不需要指定 class 中的字段时,我必须指定它是非常不自然的。
是否有任何方法可以让 Traceur 以与 Java 相同的方式解释 classes? (即未指定时自动插入,等等)
据我所知,不。
在Java、C#、C++等中这是编译器的特性,不是执行。这意味着它是隐式完成的,编译器所做的是将正确的地址放入 this
并以正确的方式引用变量。大多数编译器都有一个规则,如果你有一个同名的局部变量(在局部范围内),它具有成员变量的优先级。
虽然在 javascript 中,您可以通过 call
、apply
或 bind
轻松替换 this
,并让您的函数被调用 over 作者不打算使用的对象(即 this
可能是具有不同结构的对象)。我认为这就是为什么语言语法要求您始终明确指定您是指范围还是 this
.
更多 javascript 函数体实际上可以读取全局范围,因此定义 window.member
(如果在浏览器中)可能会改变函数的行为,如果您不使用显式 this
据我所知,ES6中没有这个功能
由于 Java脚本允许在父作用域中引用变量,因此这种类型的功能会变得复杂。因此,它必须以某种方式辨别一行代码是否像:
ticks = 0;
表示
this.ticks = 0;
或者是否表示通过名称ticks
引用当前或父作用域中的变量。
仅向对象添加 属性 可能会在 属性 引用与局部变量或一样的名字。那很可能会一团糟。现在,您必须为局部变量命名范围,以避免与 属性 名称发生冲突。而且,如果您必须限定局部变量的范围,那么您只是重新引入了一段您试图摆脱的额外语法。
Java 可以容忍这一点,因为编译器预先知道所有 属性 名称,因此如果存在冲突它可以报告错误。 Java脚本允许动态添加属性(随时添加),因此解析器实际上不知道在解析时什么 属性 名称会或不会出现在任何给定对象上,因此它不会发出警告关于冲突。这只是语言 parse/compile 和工作方式的内在差异,因此导致在表达代码时存在一些不同的功能或要求。
可以使用 with
结构来避免一些输入,但是 with
正在从 Java 脚本中删除(在严格模式下不允许),原因详述 here,没有增强,所以不是推荐的方法。
如果你想避免在构造函数中(或任何地方)分配实例变量时必须键入 this
,你可以使用 _.extend()
// this, this, this
this.a = true;
this.b = 2;
this.c = "three";
// becomes...
_.extend(this, {
a: true,
b: 2,
c: "three"
});
作为可能的简单说明,您可以预处理 classes 以插入 this.
用于一组预定义的 属性 名称,例如通过每个 class 的自定义静态元配置,可用于 gulp
构建文件。
DEBUG ClassPreprocessor: buildSync [ 'logger',
'context',
'config',
'startedComponents',
'components',
'requiredComponents' ]
regex ([^a-z\.'])(logger|context|config|startedComponents|components|requiredComponents)([^a-z:'])
replaceWith this.
从指定的道具名称开始,现在我正在构建一个正则表达式来预处理 class。但是,这非常脆弱,因为它不是基于令牌的。稍后,我想通过 AST 上的 Babel 转换器尝试类似的东西。