user13848261
user13848261

Reputation:

Dart: why do class methods work the same using this.variableName or variableName?

I was wondering if it was purposefully designed to be able to use two different ways in writing class methods, inside of which an instance property is refered to, this might sound vague so I provided a little code snippet to illustrate my point.

At first, I was under the impression that we use this.age instead of age because the latter would modify all the instances age property, but when I tried with & without the this. keyword it only changed the instance on which the method changeAge is used.

Is there a purpose for having two ways of writing this?

class Person{
  String name;
  int age;
  Person({this.name, this.age});
  
  void changeAge(int a){
    this.age = a; // why can this be written: age = a; and achieve same result?
  }
  }
void main(){
  Person foo = Person(name: 'foo', age: 16);
  Person bar = Person(name: 'bar', age: 30);
  foo.changeAge(99);
  print(foo.age); // prints 99
  print(bar.age); // prints 30 
}

Upvotes: 0

Views: 40

Answers (2)

lrn
lrn

Reputation: 71623

Dart uses the lexical scope to look up the meaning of identifiers. When you write age, the compiler:

  1. Checks first whether there is a local variable names age in the current function.
  2. Then it checks whether there is a parameter, or type parameter, of the surrounding function named age.
  3. Then it checks whether there is a declaration named age in the surrounding class (which there is in Person). This can be either an instance declaration or a static declaration.
  4. Then it checks for a the type parameter of the class named age, if the class is generic.
  5. Then it checks the current library for a top-level declaration named age.
  6. Then it checks for an imported declaration named age.

If it finds any declaration, then it considers age as referring to that. If what it found was a static declaration, then age is equivalent to ClassName.age. If it found an instance declaration, then age is equivalent to this.age.

If it found nothing, and it's inside an instance method, then it treats age as this.age, and it's an error if there is no inherited age instance member in the current class.

So, in this case, the reason age = a; and this.age = a; is the same is that age resolves to the instance variable of the surrounding class.

You don't have to write this.age, but you can, which is why you can write your changeAge method as:

  void changeAge(int age){
    this.age = age; // `this.age` is the field, `age` refers to the parameter.
  }

Upvotes: 2

TSR
TSR

Reputation: 20406

"The this keyword is used to refer the current class object. It indicates the current instance of the class, methods, or constructor. It can be also used to call the current class methods or constructors. It eliminates the uncertainty between class attributes and the parameter names are the same. If we declare the class attributes same as the parameter name, that situation will create ambiguity in the program, then the this keyword can remove the ambiguity by prefixing the class attributes. It can be passed as an argument in the class method or constructors."

In short, Dart will search for a class property called "age" if you don't use this.

If your function has already declared a variable called "age" dart will refer to that variable. To refer to the class property instead, now you can use the this keyword

Changing a class property of an instance won't affect the property of other instances. It has nothing to do with the this keyword. That's just an OOP principle, it's the same on other OOP language .

Your foo and bar are completely independent instances of Person

Upvotes: 0

Related Questions