JavaScript Objects

Objects are containers that encapsulate data, meaning all of the relevant data and functions for the thing that the variable name represents are kept together in a “capsule”, better known as an object that can be created and manipulated in programs as a single unit.

Are Objects a data type?

Yes, there are two different kinds of data types: primitives, and objects. A primitive data type is a single simple data value with no additional properties and methods. They are: numbers, strings, booleans, undefined, null and symbol. Here’s a good blog about it. Everything that is not a primitive is an object.

Types of Objects

Arrays

Sometimes variables hold one piece of information at a time: one number, one string, one element on a page. But often, we need to group things together. For example, what if we wanted to have a list of the months of the year? We’d use an array, which is just a list of things grouped together. An array looks like this:

JavaScript

  // usually like this
  let months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'november', 'december'];

  // but you can also indent it like for readability
  months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'November',
    'December'
  ];

You can put variables and expressions in your arrays, or even other arrays:

JavaScript

  let variableString = "I'm a variable!";
  let variables = [variable, "I'm not a variable!"];

  console.log(variables);
  // would log (2) ["I'm a variable!", "I'm not a variable!"]

  let numbers = [62, 62 / 2];

  console.log(numbers);
  // would log (2) [62, 31]

  let randomItems = [
    'Daniel',
    42,
    ['Brian', 456],
    3.14,
    'yet another string'
  ];

  console.log(randomItems);
  // would log (5) ["Daniel", 42, Array(2), 3.14, "yet another string"]

(5) means that the array has that number of elements. Array(2) just means that that element of the array is itself an array containing that many elements.

Just like numbers and strings, arrays have methods. You can think of a method as an action that data can perform or have taken on it. Here are a some examples of array methods:

JavaScript

  let fruits = ['bananas', 'dates', 'grapes', 'oranges'];
  fruits.pop();

  console.log(fruits);
  // would log (3) ["bananas", "dates", "grapes"]

JavaScript

  let favoriteNumbers = [9, 7, 1];
  favoriteNumbers.reverse();

  console.log(favoriteNumbers);
  // would log (3) [1, 7, 9]

Note that both the methods pop and reverse change the array on which they’re called. The pop method removes the last item from the array and returns it. The reverse method reverses the order of items in the array and returns that reversed array.

You can also add elements to an array, or combine two arrays:

JavaScript

  let greetings = [];
  greetings.push('hi');
  greetings.push('hello');

  console.log(greetings);
  // would log (2) ["hi", "hello"]

  greetings.concat(['hola', 'buenos dias']);
  // would return (4) ["hi", "hello", "hola", "buenos dias"]

  console.log(greetings);
  // would log (2) ["hi", "hello"]

Note that while the push method adds an element to an array, the concat method doesn’t actually change the original array. It returns a new array that combines the two. The greetings array still only contains the 2 elements pushed on to it.

A method like push is called a mutator method. These types of methods modify the array. A method like concat is called a accessor method. These methods do not modify the array and return some representation of the array.

If you want to access an element from an array, the syntax is like selecting a letter from a string:

JavaScript

  let names = ['Angel', 'Brian', 'Christian', 'Daniel', 'David']

  console.log(names[0]);
  // would log Angel

  console.log(names[4]);
  // would log David

Just like with strings, we count array elements starting with zero. So the zeroth element of the array is ‘Angel’, and the fourth element is ‘David’.

Note that it is conventional for array variable names to be plural, thereby making it clear that the variable refers to a collection of things rather than a single thing. Following this convention will help with debugging your own code as well as making your code clearer for others.

Check out the MDN documentation for more Mutator and Accessor methods, and experiment using these methods on your own.

Functions

A function is something that performs an action.

JavaScript

  function sayHi() {
    alert('Hi!');
  };

  sayHi();

Every time we run the sayHi function it executes all JavaScript code between the opening and closing braces - { and }. In this case it pops up a dialog box with the text Hi!.

Here’s another function called saySomething:

JavaScript

  function saySomething(something) {
    alert(something);
  };

  saySomething('hello');

'hello' is called an argument to the function saySomething. In the saySomething function, that argument is assigned to the variable something - we call that variable a parameter. If you’re confused about the difference between arguments and parameters, just remember that the argument is the information you pass in, and the parameter is the variable that receives the argument. In this case, 'hello' is the argument, and something is the parameter. The parameter can then be used just like any other variable. If this is unclear, reread it and play around with writing your own functions. Be sure you understand how to write a function that uses an argument passed in.

Heres another function:

JavaScript

  function multiply (number1, number2) {
    return number1 * number2;
  };

  console.log(multiply(8, 9));
  // would log 72

The return keyword tells JavaScript to return the result from that line of code. Without a return, JavaScript will return undefined from the function, which is JavaScript’s way of saying something does not have a value.

Let’s step through exactly what happens if we call multiply(8, 9):

  1. We call the multiply function with the arguments (8, 9).
  2. The multiply function is run. The parameter number1 is set equal to 8, and the parameter number2 is set equal to 9.
  3. 8 * 9 is run.
  4. The result of 8 * 9 is returned.
  5. The multiply function ends.

Notice our variables names: number1 and number2. We could have called them n1 and n2, and it would have taken less typing. But the name number1 very clearly expresses what the variable is for, whereas n1 will require another programmer (or your future self, when you come back to your code in a few months and don’t remember exactly how it works) to figure it out from context. In this example, it would be pretty obvious what n1 is for. But if you practice choosing descriptive names now and resisting the temptation to abbreviate, you will be in the habit of doing it when you’re writing more complex code where it matters more.

Other Syntax for Declaring Functions

Another syntax for defining the multiply function is:

JavaScript

  let multiply = function (number1, number2) {
    return number1 * number2;
  }

  console.log(multiply(8, 9));
  // would log 72

These function definitions are called function literals or function expressions. The syntax presented higher up on this page:

JavaScript

  function multiply (number1, number2) {
    return number1 * number2;
  };

  console.log(multiply(8, 9));
  // would log 72

defines a function statement. The differences between function expressions and function statements are subtle and beyond the scope of this blog. Just know that both are ways of defining a function. If you’d like to read more about the difference, check out this page on MDN.

Objects

What if we want a variable to store more information about the ‘thing’ the variable represents? For example, if you were a variable and we wanted to store information about you (your name, your age, your known programming languages, if you like lemonade) in the single variable ‘you’ - we’d need more than a single string or a single array, we’d need an object!

Here is an example of myself as an object:

JavaScript

  let daniel = {
    firstName: 'Daniel',
    lastName: 'Munoz',
    age: 22,
    knownProgrammingLanguages: ['HTML', 'CSS', 'JavaScript'],
    likesLemonade: true
  };

Let’s take a look at how this object is defined. We have our variable daniel. We assign it the value of an object by using the curly braces, { }. This is called literal notation and we have used it previously to create strings by using quotes, " " and arrays by using brackets, [ ].

Inside the curly braces are five properties for our daniel object: firstName, lastName, age, knownProgrammingLanguages, and likesLemonade. Every property of a JavaScript object consists of a key-value pair. The key is the variable that describes the kind of information to be stored. The value is the specific value of the key. So, in our example, the firstName property has a key called firstName and a value of "Daniel", the lastName property has a key lastName, with a value of "Munoz" and so on with the remaining keys: age, knownProgrammingLanguages, and likesLemonade.

Each key-value pair is separated by a colon. And pairs are separated from each other with a comma.

We could write our object like this and it would also work:

JavaScript

  let daniel = {firstName: 'Daniel', lastName: 'Munoz', age: 22, knownProgrammingLanguages: ['HTML', 'CSS', 'JavaScript'], likesLemonade: true};

However, the formatting of the object with each property indented on a separate line is a convention used when writing JavaScript objects to make it easy to see each property. Imagine an object with hundreds of properties written on the same line. It would be hard of to sort out the details.

Property keys are always a JavaScript string (though quotes are not needed) that starts with a letter. Property values can be any data type: strings, numbers, Booleans, arrays, functions, or even other objects. When the value of a property is a function, we call it a method.

Here is an object with one property and one method. This method when called will make myDog “speak” by logging “Bark!” to the console.

JavaScript

  let myDog = {
    name: "Lanky",
    speak: function () {
    console.log("Bark!");
    }
  };

To keep it simple, you can think of properties as nouns and methods as verbs or actions.

To access properties and methods on objects, we can use either dot notation or bracket notation.

JavaScript

  console.log(myDog.name);
  // would log "Lanky"

  console.log(myDog['name']);
  // would log "Lanky"

  myDog.speak();
  // would log "Bark!"

  myDog['speak']();
  // would log Bark!

Dot notation is easier to write and read but bracket notation will additionally allow us to use properties with special characters, or select properties using variables. A common convention is to use bracket notation when you need the additional functionality, and use dot notation elsewhere.

Let’s create an empty new cat object. We use the curly braces to signal JavaScript to create a new object.

JavaScript

  let cat = {};

  console.log(cat);
  // would log {};

If we log cat we can see that an empty object has been created for the cat variable.

Now, let’s give our cat some properties using dot notation. Here our values are a string and a number

JavaScript

  cat.name = 'Genter';
  console.log(cat.name);
  // would log "Genter"

  cat.age = 3;
  console.log(cat.age);
  // would log 3

Now, let’s add an array for a property value:

JavaScript

  cat.colors = ['orange', 'white'];

  console.log(cat.colors);
  // would log (2) ["orange", "white"]

The value of a property comes with all of the functionality of its type. For example, we are able to use indexing on the colors array.

JavaScript

  console.log(cat.colors[0]);
  // would log "orange"

  console.log(cat.colors[1]);
  // would log "white"

We can use array methods on the colors like push which returns the new length of the array:

JavaScript

  cat.colors.push("black");
  // would return 3

  console.log(cat.colors);
  // would log (3) ["orange", "white", "black"]

we can add to properties, but it doesn’t change the value:

JavaScript

  cat.age + 10;
  // would return 13

  console.log(cat.age);
  // would log 3

We can also update any property by reassigning its value:

JavaScript

  console.log(cat.name);
  // would log "Genter"

  cat.name = "Growly";
  console.log(cat.name);
  // would log "Growly"

Let’s add a method to our cat. This will be a property with a function as a value. In this case, we’ll give our cat some meow functionality.

JavaScript

  cat.meow = function () {
    console.log('Meow!');
  }

  cat.meow();
  // would log 'Meow!'

With objects, we can use properties within other properties. What if we decided we wanted to add a greet functionality? Let’s add another method to our cat object.

JavaScript

  cat.greet = function () {
    return "Hello, I'm " + this.name + " the cat.";
  };

Notice that the greet method has a keyword of this. When this is used in an object’s method, it always refers to the object on which the method is called. So, when we run cat.greet(), this will always refer to the object, cat. (this can also be used in other places, but it gets tricky depending on its context. Here’s a good blog about this.)

Now when we run cat.greet, we get "Hello, I'm Growly the cat.".

Conclusion

Objects are an important piece to JavaScript data types. These include: arrays, functions, and objects. Without objects, a computer can not safely solve problems.

javascript
what are closures

A closure is when a function can access its scope even if the function is executed outside of it.

javascript
When to use let and const

To understand why let and const were added, it’s probably best to look at an example of when using var can get tricky.