Dart构造函数初始化顺序

时间:2016-08-29 12:33:10

标签: dart

class Base {
  num b;
  Base() {
    print("in Base");
  }

  Base.initB(b) {
    b = b;
    print("in Base.initB");
  }
}

class Point extends Base {
  num x;
  num y;
  final num f;

  Point(this.x, int y, smth, b): f=smth, super.initB(b) {
    print(this.x);
    this.y = y;
  }
}

main() {
  var a = new Point(1, 2, 3, 4); 
  // output:
  // in Base initB
  // 1
}

我正在学习Dart,但发现文档模糊不清。我想知道实例变量的初始化顺序。有两个问题:

  1. 根据我的理解,初始化顺序为x, f -> b -> y,是否正确?
  2. xf,这是第一个?

2 个答案:

答案 0 :(得分:3)

我可以理解文档似乎模糊不清。我认为对象初始化完全破坏了它,而且它在"to-fix" list上。

实际上,初始化列表的评估顺序是从左到右。你可以通过在初始化表达式中有副作用来看到它。

对超级构造函数的调用发生在最后(在VM中),或者在超级调用发生的位置(在Dart2JS中)。因此,建议您始终将超级呼叫置于最后,并且在更高版本的Dart中可能需要这样做。把它放在早期没有任何好处。

在执行了所有初始化程序列表并且已经处理了所有初始化形式(如上面的this.x)之后,该对象被认为是初始化的,然后构造函数体以超类的第一顺序执行,并具有访问权限新对象为this

设置实际对象字段时未定义。在初始化所有字段后,您才会看到该对象。在评估初始化列表时,将所有值放在堆栈上,然后在进入第一个构造函数体之前分配对象,这是一个非常有效的实现策略。

以下是显示评估顺序的an example

答案 1 :(得分:1)

我认为xf之间没有定义订单,如果是,则无关紧要。在完成x并且f的构造函数体开始执行之后,您无法从任何地方访问suber.initB(b)Point

除了您导出的顺序是正确的。