# Custom setters and getters

Sometimes it may be necessary to have custom setters and/or getters for some attributes. Structure allows you to do that using native JavaScript setters and getters. It will even support coercion.

It's important to notice that you **should not** try to access the attribute directly inside its getter or to set it directly inside its setter because it will cause infinite recursion, this is default JavaScript behavior. To access an attribute value inside its getter you should use `this.get(attributeName)`, and to set the value of an attribute a setter you should use `this.set(attributeName, attributeValue)`:

```javascript
const User = attributes({
  firstName: String,
  lastName: String,
  age: Number,
})(
  class User {
    get firstName() {
      return `-> ${this.get('firstName')}`;
    }

    set lastName(newLastname) {
      return this.set('lastName', `Mac${newLastName}`);
    }

    get age() {
      // do NOT do that. Instead, use this.get and this.set inside getters and setters
      return this.age * 1000;
    }

    // this is NOT an attribute, just a normal getter
    get fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
);

const user = new User({ firstName: 'Connor', lastName: 'Leod' });

user.firstName; // -> Connor
user.lastName; // MacLeod
user.fullName; // -> Connor MacLeod
```

## Inheritance

Custom setters and getters are also inherited, be your superclass a pure JavaScript class or another structure:

```javascript
class Person {
  // If Person was a structure instead of a pure class, that would work too
  get name() {
    return 'The person';
  }
}

const User = attributes({
  name: String,
})(class User extends Person {});

const user = new User({ name: 'Will not be used' });

user.name; // -> The person
```

**Important**

JavaScript nativelly won't let you inherit only one of the accessors (the getter or the setter) if you define the other accessor in a subclass:

```javascript
class Person {
  get name() {
    return 'Person';
  }
}

class User extends Person {
  set name(newName) {
    this._name = newName;
  }
}

const user = new Person();
user.name = 'The user';
user.name; // -> The user
```

It happens because *once you define one of the accessors in a subclass*, all the accessors for the same attribute inherited from the superclass will be ignored.

While it's a weird behavior, Structure will follow the same functionality so the Structure classes inheritance work the same way of pure JavaScript classes, avoiding inconsistencies.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://structure.js.org/custom-setters-and-getters.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
