We use cookies to enhance your experience on the site
CodeWorlds

Creating Objects (Literals, Constructors)

In Jurassic Park we use JavaScript objects to represent many elements of our ecosystem - from dinosaurs and their behaviors, to park areas, to staff data and safety procedures. Objects are a fundamental data type in JavaScript, enabling the creation of complex data structures with properties and methods.

Object Literals

The simplest way to create objects in JavaScript is using an object literal - the curly brace

{}
notation.

1// Simple dinosaur object created with object literal
2const velociraptor = {
3  name: "Blue",
4  species: "Velociraptor",
5  age: 4,
6  length: 2.1, // meters
7  weight: 80, // kilograms
8  maxSpeed: 64, // km/h
9  diet: "carnivore",
10  location: "Sector B",
11  dangerous: true
12};
13
14console.log(velociraptor.name); // "Blue"
15console.log(velociraptor.species); // "Velociraptor"
16console.log(velociraptor.maxSpeed); // 64

Accessing Properties

We can access object properties in two ways:

1// Dot notation
2console.log(velociraptor.diet); // "carnivore"
3
4// Bracket notation (useful when property name is stored in a variable)
5const propertyName = "location";
6console.log(velociraptor[propertyName]); // "Sector B"
7
8// Bracket notation is also useful when property name contains special characters or spaces
9const dinoDetails = {
10  "full name": "Velociraptor antirrhopus",
11  "security-level": "Alpha"
12};
13
14console.log(dinoDetails["full name"]); // "Velociraptor antirrhopus"
15console.log(dinoDetails["security-level"]); // "Alpha"

Object Methods

Objects can also contain functions, which we call methods:

1const velociraptor = {
2  name: "Blue",
3  species: "Velociraptor",
4  age: 4,
5  hunger: 50, // percent (0-100)
6  health: 100, // percent (0-100)
7
8  // Method to feed the dinosaur
9  feed: function() {
10    if (this.hunger <= 0) {
11      return "Blue is not hungry.";
12    }
13
14    this.hunger -= 30;
15    if (this.hunger < 0) this.hunger = 0;
16
17    return "Blue was fed. Hunger level: " + this.hunger + "%";
18  },
19
20  // Shorter method syntax (introduced in ES6)
21  makeSound() {
22    return "Blue makes a sharp, piercing sound!";
23  },
24
25  // Method checking health status
26  checkStatus() {
27    return `Dinosaur: ${this.name} (Species: ${this.species})
28Health status: ${this.health}%
29Hunger level: ${this.hunger}%
30Overall condition: ${this.health > 80 ? "Excellent" : this.health > 50 ? "Good" : "Requires veterinary care"}`;
31  }
32};
33
34console.log(velociraptor.makeSound()); // "Blue makes a sharp, piercing sound!"
35console.log(velociraptor.feed()); // "Blue was fed. Hunger level: 20%"
36console.log(velociraptor.checkStatus());

The

this
keyword in methods refers to the object on which the method is called.

Dynamically Adding and Removing Properties

We can dynamically add and remove properties from JavaScript objects:

1const rex = {
2  name: "Rex",
3  species: "Tyrannosaurus Rex"
4};
5
6// Adding properties
7rex.age = 12;
8rex.health = 100;
9rex.zone = "A";
10rex["last-feeding"] = "2024-01-15";
11
12console.log(rex);
13// { name: "Rex", species: "Tyrannosaurus Rex", age: 12, health: 100, zone: "A", "last-feeding": "2024-01-15" }
14
15// Removing a property
16delete rex.zone;
17console.log(rex.zone); // undefined

Constructor Functions

When we need to create multiple objects with the same structure, we use constructor functions. They are called with the

new
keyword:

1// Constructor function (convention: capitalize first letter)
2function Dinosaur(name, species, weight, isDangerous) {
3  // `this` refers to the new object being created
4  this.name = name;
5  this.species = species;
6  this.weight = weight;
7  this.isDangerous = isDangerous;
8  this.health = 100;
9  this.hunger = 0;
10
11  // Method defined in constructor
12  this.feed = function() {
13    this.hunger = Math.max(0, this.hunger - 30);
14    return `${this.name} was fed. Hunger: ${this.hunger}%`;
15  };
16
17  this.roar = function() {
18    return `${this.name} (${this.species}) roars!`;
19  };
20}
21
22// Creating instances with `new`
23const rex = new Dinosaur("Rex", "T-Rex", 8000, true);
24const blue = new Dinosaur("Blue", "Velociraptor", 15, true);
25const stego = new Dinosaur("Stego", "Stegosaurus", 3500, false);
26
27console.log(rex.name);        // "Rex"
28console.log(blue.species);    // "Velociraptor"
29console.log(stego.isDangerous); // false
30
31rex.roar();  // "Rex (T-Rex) roars!"
32blue.feed(); // "Blue was fed. Hunger: 0%"
33
34// instanceof check
35console.log(rex instanceof Dinosaur);   // true
36console.log(blue instanceof Dinosaur);  // true

ES6 Classes

ES6 introduced cleaner class syntax - under the hood it's still the same prototype-based mechanism:

1class Dinosaur {
2  constructor(name, species, weight, isDangerous = false) {
3    this.name = name;
4    this.species = species;
5    this.weight = weight;
6    this.isDangerous = isDangerous;
7    this.health = 100;
8    this.hunger = 0;
9  }
10
11  feed(amount = 30) {
12    this.hunger = Math.max(0, this.hunger - amount);
13    return `${this.name} was fed. Hunger: ${this.hunger}%`;
14  }
15
16  roar() {
17    return `${this.name} (${this.species}) roars!`;
18  }
19
20  getStatus() {
21    return {
22      name: this.name,
23      health: this.health,
24      hunger: this.hunger,
25      condition: this.health > 80 ? 'Excellent' : 'Requires attention'
26    };
27  }
28}
29
30const rex = new Dinosaur("Rex", "T-Rex", 8000, true);
31rex.feed();
32console.log(rex.getStatus());
33// { name: 'Rex', health: 100, hunger: 0, condition: 'Excellent' }

Inheritance with Classes

Classes make implementing inheritance straightforward:

1// Base class
2class Animal {
3  constructor(name, species) {
4    this.name = name;
5    this.species = species;
6    this.alive = true;
7  }
8
9  makeSound() {
10    return "The animal makes a sound";
11  }
12}
13
14// Derived class inheriting from Animal
15class Dinosaur extends Animal {
16  constructor(name, species, diet) {
17    // Call the parent class constructor
18    super(name, species);
19    this.diet = diet;
20    this.health = 100;
21  }
22
23  // Override the parent method
24  makeSound() {
25    if (this.diet === "carnivore") {
26      return "ROAR!!! A terrifying roar!";
27    } else {
28      return "A gentle, low rumble.";
29    }
30  }
31
32  // Add new methods
33  eat(food) {
34    if (this.diet === "carnivore" && food.type === "meat") {
35      return `${this.name} devours ${food.name} with appetite!`;
36    } else if (this.diet === "herbivore" && food.type === "plant") {
37      return `${this.name} nibbles on ${food.name} contentedly.`;
38    } else {
39      return `${this.name} is not interested in eating ${food.name}.`;
40    }
41  }
42}
43
44// Food objects
45const meat = { name: "meat", type: "meat" };
46const plants = { name: "plants", type: "plant" };
47
48// Create dinosaur instances
49const rex = new Dinosaur("Rex", "Tyrannosaurus", "carnivore");
50const spike = new Dinosaur("Spike", "Stegosaurus", "herbivore");
51
52console.log(rex.makeSound()); // "ROAR!!! A terrifying roar!"
53console.log(spike.makeSound()); // "A gentle, low rumble."
54
55console.log(rex.eat(meat)); // "Rex devours meat with appetite!"
56console.log(rex.eat(plants)); // "Rex is not interested in eating plants."
57console.log(spike.eat(plants)); // "Spike nibbles on plants contentedly."

Static Methods

Static methods are called on the class itself, not on its instances:

1class DinosaurDatabase {
2  static dinoCount = 0;
3
4  constructor(name, species) {
5    this.name = name;
6    this.species = species;
7    DinosaurDatabase.dinoCount++;
8  }
9
10  // Instance method - requires creating an object
11  getInfo() {
12    return `${this.name} (${this.species})`;
13  }
14
15  // Static method - called on the class, not on an instance
16  static getTotalDinosaurCount() {
17    return `Total dinosaurs in the database: ${DinosaurDatabase.dinoCount}`;
18  }
19
20  static compareAge(dino1, dino2) {
21    if (!dino1.age || !dino2.age) return "Age data missing.";
22
23    if (dino1.age > dino2.age) {
24      return `${dino1.name} is older than ${dino2.name}.`;
25    } else if (dino1.age < dino2.age) {
26      return `${dino1.name} is younger than ${dino2.name}.`;
27    } else {
28      return `${dino1.name} and ${dino2.name} are the same age.`;
29    }
30  }
31}
32
33const dino1 = new DinosaurDatabase("Rex", "Tyrannosaurus");
34dino1.age = 8;
35
36const dino2 = new DinosaurDatabase("Blue", "Velociraptor");
37dino2.age = 4;
38
39const dino3 = new DinosaurDatabase("Trixie", "Triceratops");
40dino3.age = 6;
41
42console.log(DinosaurDatabase.getTotalDinosaurCount()); // "Total dinosaurs in the database: 3"
43console.log(DinosaurDatabase.compareAge(dino1, dino2)); // "Rex is older than Blue."
44console.log(DinosaurDatabase.compareAge(dino2, dino3)); // "Blue is younger than Trixie."

Object.create()

Object.create()
creates a new object with a specified prototype:

1const dinosaurPrototype = {
2  makeSound() {
3    return `${this.name} makes a sound!`;
4  },
5  eat(food) {
6    return `${this.name} eats ${food}`;
7  }
8};
9
10const rex = Object.create(dinosaurPrototype);
11rex.name = "Rex";
12rex.species = "T-Rex";
13
14console.log(rex.makeSound()); // "Rex makes a sound!"
15console.log(rex.eat("meat")); // "Rex eats meat"

Factory Functions

Factory functions return new objects - an alternative to constructors and classes:

1function createDinosaur(name, species, weight) {
2  // Private variable - not accessible from outside
3  let _health = 100;
4  let _hunger = 0;
5
6  // Public interface
7  return {
8    name,
9    species,
10    weight,
11
12    feed() {
13      _hunger = Math.max(0, _hunger - 30);
14      return `${name} was fed`;
15    },
16
17    getHealth() { return _health; },
18    getHunger() { return _hunger; },
19
20    takeDamage(amount) {
21      _health = Math.max(0, _health - amount);
22      return _health;
23    }
24  };
25}
26
27const rex = createDinosaur("Rex", "T-Rex", 8000);
28rex.feed();
29console.log(rex.getHunger()); // 0
30// console.log(rex._hunger); // undefined - private!

Dinosaur Manager System

1class DinosaurManager {
2  constructor(parkName) {
3    this.parkName = parkName;
4    this.dinosaurs = new Map();
5    this.zones = new Map();
6  }
7
8  addDinosaur(dino) {
9    this.dinosaurs.set(dino.name, dino);
10    console.log(`${dino.name} registered in ${this.parkName}`);
11    return this;
12  }
13
14  addZone(zoneId, type) {
15    this.zones.set(zoneId, { type, dinosaurs: [] });
16    return this;
17  }
18
19  assignToZone(dinoName, zoneId) {
20    const dino = this.dinosaurs.get(dinoName);
21    const zone = this.zones.get(zoneId);
22
23    if (!dino || !zone) {
24      throw new Error(`Dinosaur ${dinoName} or zone ${zoneId} not found`);
25    }
26
27    dino.zone = zoneId;
28    zone.dinosaurs.push(dinoName);
29    console.log(`${dinoName} assigned to zone ${zoneId}`);
30    return this;
31  }
32
33  getZoneReport(zoneId) {
34    const zone = this.zones.get(zoneId);
35    if (!zone) return null;
36
37    return {
38      zoneId,
39      type: zone.type,
40      count: zone.dinosaurs.length,
41      dinosaurs: zone.dinosaurs.map(name => {
42        const d = this.dinosaurs.get(name);
43        return `${d.name} (${d.species})`;
44      })
45    };
46  }
47}
48
49const manager = new DinosaurManager("Jurassic Park");
50manager
51  .addZone("A", "CARNIVORES")
52  .addZone("B", "HERBIVORES");
53
54const rex = new Dinosaur("Rex", "T-Rex", 8000, true);
55const stego = new Dinosaur("Stego", "Stegosaurus", 3500, false);
56
57manager
58  .addDinosaur(rex)
59  .addDinosaur(stego)
60  .assignToZone("Rex", "A")
61  .assignToZone("Stego", "B");
62
63console.log(manager.getZoneReport("A"));
64// { zoneId: 'A', type: 'CARNIVORES', count: 1, dinosaurs: ['Rex (T-Rex)'] }

Summary

Objects are a fundamental element of JavaScript and allow us to model complex data structures and behaviors. In Jurassic Park, we use them to represent everything - from dinosaurs to the entire park management system.

We have several ways to create objects:

  1. Object literals - the simplest approach, ideal for single, unique objects
  2. Constructor functions - when we need to create many similar objects
  3. Classes (ES6+) - modern, readable syntax for creating object templates with inheritance
  4. Object.create() - creating objects with a specified prototype
  5. Factory functions - functions that return new objects, an alternative to constructors

The choice of technique depends on the situation and project needs. In complex applications like our Jurassic Park management system, we typically use a combination of these techniques.

"Objects are like dinosaur DNA files in our lab" - says Dr. Rex. "Each file (object) contains properties (DNA data) and methods (how the organism behaves). Constructor functions and classes are like templates for creating new files - once you define the structure, you can use it to create many similar objects!"

Go to CodeWorlds