Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An initializing formal parameter is a syntactic construct in Dart constructors that directly assigns an incoming argument to an instance variable. By using this.propertyName within the constructor’s parameter list, the Dart compiler automatically binds the argument to the corresponding field and performs the assignment during the initialization phase, before the constructor body executes.

Syntax and Mechanics

The syntax replaces the standard parameter declaration with this. followed by the exact name of the instance variable.
class Point {
  final double x;
  final double y;

  // 'this.x' and 'this.y' are initializing formal parameters
  Point(this.x, this.y); 
}
Because this assignment happens prior to the constructor body, initializing formals are fully compatible with final (immutable) and non-nullable instance variables. Type Inference The type of an initializing formal parameter is implicitly derived from the instance variable it initializes. The Dart language specification allows explicitly providing a type on an initializing formal (e.g., Point(double this.x)). However, doing so is redundant and triggers a style lint (type_init_formals, an “info” level diagnostic by default), rather than a compile-time warning or error.

Lexical Scoping and Resolution

Crucially, an initializing formal parameter does not introduce a local variable into the constructor’s formal parameter scope. Because no local variable is created, any reference to the parameter’s identifier within the constructor resolves directly to the instance member (e.g., this.x). This distinction dictates how the identifier behaves in different parts of the constructor:
  • In the initializer list: Referencing the identifier results in a compile-time error. The compiler treats it as an instance member access, which is strictly prohibited in the initializer list because the object is not yet fully initialized.
  • In the constructor body: Referencing the identifier is perfectly valid. It simply resolves to the instance getter (this.x), which is permitted because the object is fully initialized by the time the body executes.
class Point {
  final double x;
  final double y;

  // COMPILE-TIME ERROR: The instance member 'x' can't be accessed in an initializer.
  // 'x' resolves to 'this.x', not a local parameter variable.
  Point.invalid(this.x) : y = x * 2; 
  
  // CORRECT APPROACH FOR INITIALIZER LIST: Use a regular formal parameter.
  Point.withInitializer(double x) : this.x = x, y = x * 2;

  // VALID: 'x' resolves to 'this.x' inside the body.
  Point.withBody(this.x, this.y) {
    print(x); // Implicitly accesses this.x
  }
}

Parameter Variations

Initializing formals can be utilized across all Dart parameter types: positional, optional positional, and named parameters. Named Parameters with Modifiers When used as named parameters, initializing formals can be combined with the required modifier or assigned default values.
class ServerConfig {
  final String host;
  final int port;
  final bool isSecure;

  ServerConfig({
    required this.host,
    this.port = 8080,
    this.isSecure = true,
  });
}
Optional Positional Parameters They can also be enclosed in square brackets [] to act as optional positional parameters, provided they have a default value or the underlying field is nullable.
class User {
  String name;
  int? age;

  User(this.name, [this.age]);
}

Compiler Constraints

  1. Constructor Restriction: Initializing formal parameters are strictly limited to constructors. They cannot be used in standard methods, top-level functions, or getters/setters.
  2. Conflict with Initializer List: An instance variable cannot be initialized by an initializing formal parameter and simultaneously assigned a value in the constructor’s explicit initializer list. Doing so results in a compile-time error.
class InvalidExample {
  int count;

  // COMPILE-TIME ERROR: 'count' is initialized twice.
  InvalidExample(this.count) : count = 0; 
}
  1. Redirection Conflict: Initializing formals cannot be used in redirecting constructors (constructors that call this(...)), as redirecting constructors are not permitted to initialize fields directly.
Master Dart with Deep Grasping Methodology!Learn More