Javascript ES6在类中无处不在使用'this'关键字

时间:2015-03-20 00:45:52

标签: javascript ecmascript-6 traceur

我正在使用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 个答案:

答案 0 :(得分:3)

AFAIK,没有。

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

在javascript中,您可以轻松地通过thiscallapply替换bind,并将您的功能称为 over 一个对象作者并不打算使用(即this可能是具有不同结构的对象)。我认为这就是为什么语言语法要求您始终明确指定您是引用范围还是this的原因。

更多javascript函数体实际上可以读取全局范围,因此如果不使用显式window.member

,定义this(如果在浏览器中)可能会改变函数的行为

答案 1 :(得分:1)

据我所知,ES6中没有这样的功能。

Javascript允许引用父作用域中的变量,这种类型的功能会变得复杂。因此,它必须以某种方式辨别是否有一行代码如:

ticks = 0;

表示

this.ticks = 0;

或者是否意味着通过名称ticks引用当前或父范围中的变量。

仅仅通过在属性引用和同名的本地变量或父作用域变量之间创建冲突,仅仅向对象添加属性可能会破坏之前正常工作的代码。这可能是一团糟。现在,您必须为您的局部变量命名范围,以避免与属性名称发生冲突。并且,如果您必须对局部变量进行范围调整,那么您只需重新引入一个您试图摆脱的额外语法。

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

可以使用with结构来避免某些输入,但是{J}(with正在从Javascript中删除(严格模式下不允许),原因详见here,未加强,所以不是推荐的方法。

答案 2 :(得分:0)

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

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

// becomes...
_.extend(this, {
  a: true,
  b: 2,
  c: "three"
});

答案 3 :(得分: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变换器尝试类似的东西。