4

我现在正在使用 Traceur 来编写一些未来的 javascript,这是我在某个类中拥有的一个函数

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 之类的,当我不需要时,在引用类中的字段时必须指定它是非常不自然的。

有没有办法让 Traceur 像 Java 一样解释类?(即在未指定时自动插入,等等)

4

4 回答 4

4

AFAIK,不。

在 Java、C#、C++ 等中,这是编译器的一个特性,而不是执行。这意味着它是隐式完成的,编译器所做的是以正确的this方式将正确的地址放入并引用变量。大多数编译器都有一条规则,如果你有一个同名的局部变量(在局部范围内),它优先于成员变量。

在 javascript 中,您可以轻松地替换thisvia callapply或者bind让您的函数在作者不打算使用的对象上调用(即可能this是具有不同结构的对象)。我认为这就是语言语法要求您始终明确指定您是指范围还是this.

javascript 函数体中的更多内容实际上可以读取全局范围,因此window.member如果您不使用显式定义(如果在浏览器中)可能会改变函数的行为this

于 2015-03-20T00:56:01.217 回答
1

据我所知,ES6 中没有这样的特性。

由于 Javascript 允许在父范围内引用变量,这种类型的功能会变得复杂。因此,它必须以某种方式辨别一行代码是否像:

ticks = 0;

方法

this.ticks = 0;

或者它是否意味着通过ticks.

通过在属性引用和同名的局部变量或父作用域变量之间产生冲突,仅仅将属性添加到对象可能会弄乱之前运行良好的代码。那很可能是一团糟。现在,您必须为局部变量命名范围,以避免与属性名称发生冲突。而且,如果您必须限定局部变量的范围,那么您只是重新引入了一段您试图摆脱的额外语法。

Java 可以容忍这种情况,因为编译器预先知道所有属性名称,因此如果发生冲突,它可以报告错误。Javascript 允许动态添加属性(随时添加),因此解析器实际上并不知道在解析时任何给定对象上会或不会出现什么属性名称,因此它无法警告冲突。这只是语言解析/编译和工作方式的固有差异,因此导致表达代码的一些不同的能力或要求。

可以使用该with结构来避免某些类型的输入,但由于此处with详述的原因而从 Javascript 中删除(在严格模式下不允许),而不是增强,因此不推荐使用该方法。

于 2015-03-20T00:59:58.663 回答
0

如果您想避免this在构造函数(或任何地方)中分配实例变量时必须键入,您可以使用_.extend()

// this, this, this
this.a = true;
this.b = 2;
this.c = "three";

// becomes...
_.extend(this, {
  a: true,
  b: 2,
  c: "three"
});
于 2015-03-20T01:46:41.387 回答
0

作为可能的简单说明,您可以预处理您的类以插入this.一组预定义的属性名称,例如,通过每个类的自定义静态元配置,可用于gulp构建文件。

DEBUG ClassPreprocessor: buildSync [ 'logger',
  'context',
  'config',
  'startedComponents',
  'components',
  'requiredComponents' ] 
regex ([^a-z\.'])(logger|context|config|startedComponents|components|requiredComponents)([^a-z:'])
replaceWith $1this.$2$3

从指定的道具名称中,现在我正在构建一个正则表达式来预处理类。不过,这非常脆弱,因为它不是基于令牌的。稍后,我想通过 AST 上的 Babel 转换器尝试类似的东西。

于 2016-04-10T10:00:05.587 回答