JavaScript Notes 5 Objects

BY Guanqiao Huang

Posted by HUANG on December 27, 2018

Objects

Property Assignment

  • add new properties and change the properties
const spaceship = {type: 'shuttle'};
spaceship = {type: 'alien'}; // TypeError: Assignment to constant variable.
spaceship.type = 'alien'; // Changes the value of the type property
spaceship.speed = 'Mach 5'; // Creates a new key of 'speed' with a value of 'Mach 5'
  • delete a property from an object

  • delete objectName['Property Name'];

  • delete objectName.propName;

const spaceship = {
  'Fuel Type': 'Turbo Fuel',
  homePlanet: 'Earth',
  mission: 'Explore the universe'
};

delete spaceship.mission;  // Removes the mission property

Looping Through Objects

let spaceship = {
    crew: {
    captain: { 
        name: 'Lily', 
        degree: 'Computer Engineering', 
        cheerTeam() { console.log('You got this!') } 
        },
    'chief officer': { 
        name: 'Dan', 
        degree: 'Aerospace Engineering', 
        agree() { console.log('I agree, captain!') } 
        },
    medic: { 
        name: 'Clementine', 
        degree: 'Physics', 
        announce() { console.log(`Jets on!`) } },
    translator: {
        name: 'Shauna', 
        degree: 'Conservation Science', 
        powerFuel() { console.log('The tank is full!') } 
        }
    }
}; 

// Write your code below
for(let crewNumber in spaceship.crew){
   console.log(`${crewNumber}: ${spaceship.crew[crewNumber].name}`)
}

for(let crewNumber in spaceship.crew){
  console.log(`${spaceship.crew[crewNumber].name}: ${spaceship.crew[crewNumber].degree}`);
}

Output

captain: Lily
chief officer: Dan
medic: Clementine
translator: Shauna
Lily: Computer Engineering
Dan: Aerospace Engineering
Clementine: Physics
Shauna: Conservation Science

Review Objects

  • Objects store collections of key-value pairs.
  • Each key-value pair is a property—when a property is a function it is known as a method.
  • An object literal is composed of comma-separated key-value pairs surrounded by curly braces.
  • You can access, add or edit a property within an object by using dot notation or bracket notation.
  • We can add methods to our object literals using key-value syntax with anonymous function expressions as values or by using the new ES6 method syntax.
  • We can navigate complex, nested objects by chaining operators.
  • Objects are mutable—we can change their properties even when they’re declared with const.
  • Objects are passed by reference— when we make changes to an object passed into a function, those changes are permanent.
  • We can iterate through objects using the For…in syntax.

The this Keyword

const robot = {
  model:'1E78V2',
  energyLevel: 100,

  provideInfo(){
    return `I am ${this.model} and my current energy level is ${this.energyLevel}.`
  }
};

console.log(robot.provideInfo());

Getters

const robot = {
  _model: '1E78V2',
  _energyLevel: 100,
  get energyLevel(){
    if(typeof this._energyLevel === 'number'){
      return `My current energy level is ${this._energyLevel}`
    }else{
      return 'System malfunction: cannot retrieve energy level'
    }
  }
};

console.log(robot.energyLevel);

Setters

const robot = {
  _model: '1E78V2',
  _energyLevel: 100,
  _numOfSensors: 15,
  get numOfSensors(){
    if(typeof this._numOfSensors === 'number'){
      return this._numOfSensors;
    } else {
      return 'Sensors are currently down.'
    }
  },
  set numOfSensors(num){
      if(typeof num === 'number'){
        if(num >= 0){
          this._numOfSensors = num;
        }
        else{
          console.log('Pass in a number that is greater than or equal to 0');
        }
      }
  }
  
};

robot.numOfSensors = 100;
console.log(robot.numOfSensors);

Factory Functions

const monsterFactory = (name, age, energySource, catchPhrase) => {
  return { 
    name: name,
    age: age, 
    energySource: energySource,
    scare() {
      console.log(catchPhrase);
    } 
  }
};

const ghost = monsterFactory('Ghouly', 251, 'ectoplasm', 'BOO!');
ghost.scare(); // 'BOO!'

const robotFactory = (model, mobile) =>{
  return {
    model: model,
    mobile: mobile,
    beep(){
      console.log('Beep Boop');
    }
  }
}

const tinCan = robotFactory('P-500', true);
tinCan.beep();

Property Value Shorthand

function robotFactory(model, mobile){
  return {
    model,
    mobile,
    beep() {
      console.log('Beep Boop');
    }
  }
}

// To check that the property value shorthand technique worked:
const newRobot = robotFactory('P-501', false)
console.log(newRobot.model)
console.log(newRobot.mobile)

Destructured Assignment

const vampire = {
  name: 'Dracula',
  residence: 'Transylvania',
  preferences: {
    day: 'stay inside',
    night: 'satisfy appetite'
  }
};

const residence = vampire.residence; 
console.log(residence); // Prints 'Transylvania' 

const { residence } = vampire; 
console.log(residence); // Prints 'Transylvania'

const { day } = vampire.preferences; 
console.log(day); // Prints 'stay inside'
const robot = {
  model: '1E78V2',
  energyLevel: 100,
  functionality: {
    beep() {
      console.log('Beep Boop');
    },
    fireLaser() {
      console.log('Pew Pew');
    },
  }
};

const {functionality} = robot;
functionality.beep();
const robot = {
	model: 'SAL-1000',
  mobile: true,
  sentient: false,
  armor: 'Steel-plated',
  energyLevel: 75
};

// What is missing in the following method call?
const robotKeys = Object.keys(robot);

console.log(robotKeys);

// Declare robotEntries below this line:
const robotEntries = Object.entries(robot);
console.log(robotEntries);

// Declare newRobot below this line:
const newRobot1 = {laserBlaster: true, voiceRecognition: true};
const newRobot = Object.assign(newRobot1, robot);
//const newRobot = Object.assign(robot, {laserBlaster: true, voiceRecognition: true});
console.log(newRobot);

Advanced Objects

  • The object that a method belongs to is called the calling object.
  • The this keyword refers to the calling object and can be used to access properties of the calling object.
  • Methods do not automatically have access to other internal properties of the calling object.
  • The value of this depends on where the this is being accessed from.
  • We cannot use arrow functions as methods if we want to access other internal properties.
  • JavaScript objects do not have built-in privacy, rather there are conventions to follow to notify other developers about the intent of the code.
  • The usage of an underscore before a property name means that the original developer did not intend for that property to be directly changed.
  • Setters and getter methods allow for more detailed ways of accessing and assigning properties.
  • Factory functions allow us to create object instances quickly and repeatedly.
  • There are different ways to use object destructuring: one way is the property value shorthand and another is destructured assignment.
  • As with any concept, it is a good skill to learn how to use the documentation with objects!

s

const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: []
  },
  get appetizers(){
    return this._courses.appetizers;
  },
  set appetizers(appetizerIn){
    this._courses.appetizers = appetizerIn;
  },
  get mains(){
    return this._courses.mains;
  },
  set mains(mainsIn){
 this._courses.mains = mainsIn;
  },
  get desserts(){
return this._courses.desserts;
  },
  set desserts(dessertsIn){
 this._courses.desserts = dessertsIn;
  },
  get courses(){
    return {
      appetizers: this.appetizers,
      mains: this.mains,
      desserts: this.desserts  
      };
  },
  addDishToCourse(courseName, dishName, dishPrice){
    const dish = {
        name: dishName,
        price: dishPrice,
    };
    return this._courses[courseName].push(dish);
  },
  getRandomDishFromCourse(courseName){
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];
  },
  generateRandomMeal(){
    const appetizer = this.getRandomDishFromCourse('appetizers');
    const main = this.getRandomDishFromCourse('mains');
    const dessert = this.getRandomDishFromCourse('desserts');
    const totalprice = appetizer.price + main.price + dessert.price;
    return `Your meal is ${appetizer.name}, ${main.name}, ${dessert.name} and the total price is ${totalprice}`;
  }
};

menu.addDishToCourse('appetizers', 'salad', 4.00);
menu.addDishToCourse('appetizers', 'wings', 4.50);
menu.addDishToCourse('appetizers', 'fries', 5.00);

menu.addDishToCourse('mains', 'steak', 10.00);
menu.addDishToCourse('mains', 'salamon', 11.50);
menu.addDishToCourse('mains', 'tofu', 7.00);

menu.addDishToCourse('desserts', 'ice cream', 3.00);
menu.addDishToCourse('desserts', 'coffee', 3.50);
menu.addDishToCourse('desserts', 'cake', 3.25);

const meal = menu.generateRandomMeal();
console.log(meal);

Team Stats

const team = {
  _players: [
    {firstName: 'Pablo',lastName: 'Sanchez',age: 11},
  {firstName: 'Pabss',lastName: 'faahez',age: 25},
   {firstName: 'Adobe',lastName: 'Reader',age: 30},
   {firstName: 'Micro',lastName: 'Soft',age: 21},
],
  _games: [
{opponent: 'Broncos', teamPoints: 42, opponentPoints: 27},
{opponent: 'Wroncos', teamPoints: 26, opponentPoints: 20},
{opponent: 'Xroncos', teamPoints: 15, opponentPoints: 18},
{opponent: 'Droncos', teamPoints: 32, opponentPoints: 30}
  ],
  get players(){
    return this._players;
  },
  get games(){
    return this._games;
  },
  addPlayer(firstName, lastName, age){
    let player = {
      firstName: firstName,
      lastName: lastName,
      age: age
    };
    this.players.push(player);
  },
  addGame(opponent,teamPoints,opponentPoints){
    const game = {
      opponent:opponent,
      teamPoints:teamPoints,
      opponentPoints:opponentPoints
    }
    this.games.push(game);
  }

};


  team.addPlayer("Steph","Turry", 28);
  team.addPlayer("Ateph","Rurry", 44);
  team.addPlayer("Rteph","Vurry", 76);

  console.log(team.players);

  team.addGame("Sea Lions",100, 50);
  team.addGame("Land Lions",60, 35);
  team.addGame("Sky Lions",80, 80);

    console.log(team.games);

Add a property to object

let bikes = {
  schwinn: 'blue',
  trek: 'black'
}

bikes.specialized = 'red';
bikes['specialized'] = 'blue';

Destructured assignment

const myDog = {
  name: 'Tadpole',
  breed: 'mutt',
  color: 'tan',
  weight: 32
}
 
 let {name} = myDog;

 //Using destructured assignment, we can use this syntax to create a variable nbame with a value of myuDog's .name proerty