0
\$\begingroup\$

Setup

I am writing a class based, object oriented algorithm in typescript. In many cases, a class will create another child class, passing itself as an argument to the child class. For example:

interface RoomDetails {
  name: string;
  items: string[];
}

class House {
  rooms: Room[];

  constructor(rooms: RoomDetails[], ...other_args) {
    this.rooms = rooms.map(room => new Room(room.name, room.items, this)) // <--- here
  }
}

And in Room:

class Room {
  name: string;
  house: House;
  items: Item[];

  constructor(name: string, items: string[], house: House){
    this.name = name;
    this.house = house;
    this.items = items.map(item => new Item(item, this, house)) // <--- and here
  }
}

To go even one level deeper, in Item:

class Item {
  name: string;
  room: Room;
  house: House

  constructor(name: string, room: Room, house: House){
    this.name = name;
    this.room = room;
    this.house = house;
  }
}

So as you can see, every new Room has references to the House it belongs to, and every new Item has references to both the Room and House it belongs to. Attaching these references to children and grandchildren makes referencing their parent/grandparents quick and easy when doing further logic. And of course it creates a circular reference. So if I create a new House:

const myHouse = new House(proper_arguments_go_here)

And then I examine myHouse, I'll see that myHouse points to some Room instances - which each point back to myHouse, as well as their own Item instances - which each point back to their respective Rooms, as well as the original myHouse.

Question - is there a wise naming convention for this?

When examining myHouse, or any of its Rooms, or any of their Items, it can get a bit confusing. Some properties of a Room belong to that room only, i.e. a Room's name, and have no other references to them, other than from that class instance. But others, like Room.house, are circular references, and do not "belong" only to that class instance. Is there a good naming convention for such variables?

Possible idea - prefix with _

I had thought of prefixing these with underscores, like this:

class Item {
  name: string;
  _room: Room;
  _house: House

  constructor(name: string, room: Room, house: House){
    this.name = name;
    this._room = room;
    this._house = house;
  }
}

I know that in javascript, a variable prefixed with _ inside a class typically intends to mark that variable as private. But private variables don't really exist in javascript, and in typescript, we use the private keyword to create private variables.

Would it be a bad idea / convention to prefix all circular reference class properties with _? Is there a better naming convention for such variables?

\$\endgroup\$
3
  • \$\begingroup\$ "every new Item has references to both the Room and House it belongs to" Why sabotage yourself? Why do this when you can find the house from the room the item belongs to? Why would item.house be so much better than item.room.house? \$\endgroup\$
    – BCdotWEB
    Jun 11 at 5:22
  • \$\begingroup\$ That's a fair question. In my real code that inspired this question, the chain has gotten 4 levels deep in some places, and may get deeper. And at some of the deeper levels, say price.item.room.house, I need to access myHouse various times through various methods, and this.item.room.house gets very verbose, as opposed to say, this._house. 1:**Why would you say this is sabatoging myself? And **2: even if I hold to only 1-level deep of circular reference per class, is there a good naming convention for those references? I appreciate your comment but it doesn't answer my question \$\endgroup\$ Jun 11 at 14:26
  • \$\begingroup\$ 1. In case if you need something private, you can leverage private keywoard like this class Item { constructor(public name: string, private room: Room, private house: House){} } 2. Try naming storedInRoom and belongsToHouse 3. It's really rare that circular reference helps code to be readable. Try to avoid that. \$\endgroup\$ Aug 11 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.