A closure is when a function can access its scope even if the function is executed outside of it.
To understand why let and const were added, it’s probably best to look at an example of when using var can get tricky.
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.
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.
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.
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)
:
multiply
function with the arguments
(8, 9)
.multiply
function is run. The parameter
number1
is set equal to 8
, and the parameter
number2
is set equal to 9
.8 * 9
is run.8 * 9
is returned.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.
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.
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."
.
Objects are an important piece to JavaScript data types. These include: arrays, functions, and objects. Without objects, a computer can not safely solve problems.
A closure is when a function can access its scope even if the function is executed outside of it.
To understand why let and const were added, it’s probably best to look at an example of when using var can get tricky.