Create and Modify Properties
Creating Objects
To create a new, blank (i.e., “empty”) object, you can use object literal notation, or theObject()
constructor function. If you're not familiar with constructor functions, no need to worry! We'll jump into them in-depth in Lesson 3. For now, just know that the following two expressions are equivalent:
// Using literal notation:
const myObject = {};
// Using the Object() constructor function:
const myObject = new Object();
While both methods ultimately return an object without properties of its own, theObject()
constructor function is a bit slower and more verbose. As such, the recommended way to create new objects in JavaScript is to use literal notation.
Modifying Properties
Keep in mind that data within objects are mutable, meaning that data can be changed. There are a few exceptions to this, but for now, let's see how we can modify/reassign existing properties in an object.
Consider the followingcat
object:
const cat = {
age: 2,
name: 'Bailey',
meow: function () {
console.log('Meow!');
},
greet: function (name) {
console.log(`Hello ${name}`);
}
};
Now, let's go ahead change it up a bit!
cat.age += 1;
cat.age;
// 3
cat.name = 'Bambi';
cat.name;
// 'Bambi'
After incrementing the value of theage
property by 1, and reassigningname
's value to'Bambi'
, ourcat
object now looks like:
{
age: 3,
name: 'Bambi',
meow: function () {
console.log('Meow!');
},
greet: function (name) {
console.log(`Hello ${name}`);
}
};
Adding Properties
Properties can be added to objects simply by specifying the property name, then giving it a value. Let's start off with a blank object, then add two properties:
const printer = {};
printer.on = true;
printer.mode = 'black and white';
The above example uses dot notation to add properties, but keep in mind that square bracket notation works just as well:
printer['remainingSheets'] = 168;
Likewise, we can add a method to theprinter
object in a similar manner. This time, the value of the property is an anonymous (i.e., unnamed) function:
printer.print = function () {
console.log('The printer is printing!');
};
Great! The completeprinter
object now looks like the following:
{
on: true,
mode: 'black and white',
remainingSheets: 168,
print: function () {
console.log('The printer is printing!');
}
}
Removing Properties
Recall that since objects are mutable, not only can we modify existing properties (or even add new ones) -- we can also _delete _properties from objects.
Say that theprinter
object above actually doesn't have any modes (i.e.,'black and white'
,'color'
, etc.). We can go ahead and remove that property fromprinter
using thedelete
operator.
delete printer.mode;
// true
Note thatdelete
directly mutates the object at hand. If we try to access a deleted property, the JavaScript interpreter will no longer be able to find themode
property because themode
key (along with its value,true
) have been deleted:
printer.mode;
// undefined
Great! Let's see this all in action below. <- video!
Here's the code from the preceding video.
QUESTION 1 OF 6
What is true about modifying objects? Select all that apply:
Removing properties with the
delete
operator returnstrue
upon successful deletion.Accessing a deleted property (i.e., a property that no longer exists) returns
<-null
.undefined
With a few exceptions, properties in objects aremutable.
Properties can be added to objects
exclusivelywith square bracket notation.
SUBMIT
Consider the followinghouse
object:
let house = {
color: 'green',
numRooms: 4,
numWindows: 8,
forSale: false
};
Write an expression to delete thenumWindows
property fromhouse
.
SUBMIT: delete house.numWindows;
Consider the updatedhouse
object from above:
let house = {
color: 'green',
numRooms: 4,
forSale: false
};
Write an expression to add a newhasGarage
property tohouse
. Set the value of thehasGarage
property totrue
.
SUBMIT: house.hasGarage = true;
or house['hasGarage'] = ture;
Passing Arguments
Passing a Primitive
In JavaScript, a primitive (e.g., a string, number, boolean, etc.) is immutable. In other words, any changes made to an argument inside a function effectively creates a _copy _local to that function, and does _not _affect the primitive _outside _of that function. Check out the following example:
function changeToEight(n) {
n = 8; // whatever n was, it is now 8... but only in this function!
}
let n = 7;
changeToEight(n);
console.log(n);
// 7
changeToEight()
takes in a single argument,n
, and changes it to8
. However, this change only exists inside the function itself. We then pass the global variablen
(which is assigned the value7
) into the function. After invoking it,n
is still equal to7
.
Passing an Object
On the other hand, objects _in JavaScript are _mutable. If you pass an object into a function, Javascript passes a _reference _to that object. Let's see what happens if we pass an object into a function and then modify a property:
let originalObject = {
favoriteColor: 'red'
};
function setToBlue(object) {
object.favoriteColor = 'blue';
}
setToBlue(originalObject);
originalObject.favoriteColor;
// 'blue'
In the above example,originalObject
contains a single property,favoriteColor
, which has a value of'red'
. We passoriginalObject
into thesetToBlue()
function and invoke it. After accessingoriginalObject
'sfavoriteColor
property, we see that the value is now'blue'
!
How did this happen? Well, since objects in JavaScript are passed by reference, if we make changes to that reference, we're actually directly modifying the original object itself!
What's more: the same rule applies when re-assigning an object to a new variable, and then changing_that_copy. Again, since objects are passed by reference, the original object is changed as well. Let's take a look at this more closely with another example.
Consider thisiceCreamOriginal
object, which shows the amount of ice cream cones each instructor has eaten:
const iceCreamOriginal = {
Andrew: 3,
Richard: 15
};
Let's go ahead and make assign a new variable toiceCreamOriginal
. We'll then check the value of itsRichard
property:
const iceCreamCopy = iceCreamOriginal;
iceCreamCopy.Richard;
// 15
As expected, the expressioniceCreamCopy.Richard;
returns15
(i.e., it is the same value as theRichard
property iniceCreamOriginal
). Now, let's change the value in the copy, then check the results:
iceCreamCopy.Richard = 99;
iceCreamCopy.Richard;
// 99
iceCreamOriginal.Richard;
// 99
Since objects are passed by reference, making changes to the copy (iceCreamCopy
) has a direct effect on the original object (iceCreamOriginal
) as well. In both objects, the value of theRichard
property is now99
.
Comparing an Object with Another Object
On the topic of references, let's see what happens when we compare one object with another object. The following objects,parrot
andpigeon
, have the same methods and properties:
const parrot = {
group: 'bird',
feathers: true,
chirp: function () {
console.log('Chirp chirp!');
}
};
const pigeon = {
group: 'bird',
feathers: true,
chirp: function () {
console.log('Chirp chirp!');
}
};
Naturally, one might expect theparrot
object andpigeon
object to beequal. After all, both objects look exactly the same! Let's compareparrot
andpigeon
to find out:
parrot === pigeon;
// false
What's going on here? As it turns out, the expression will only returntrue
when comparing two_references_to exactly the same object. Using what we now know about passing objects, let's confirm this. To start off, let's create a new variable,myBird
, and assign it to one of the objects above:
const myBird = parrot;
As we've just learned,myBird
not only refers to the same object asparrot
-- they_are_the same object! If we make any updates tomyBird
's properties,parrot
's properties will be updated with exactly the same changes as well. Now, the comparison will return true:
myBird === parrot;
// true
So sincepigeon
is_not_the same object asmyBird
orparrot
, any comparisons betweenmyBird
andpigeon
will returnfalse
:
myBird === pigeon;
// false
QUESTION 4 OF 6
Which of the following is immutable? Select all that apply:
8
'How are you today?'
{ numProperties: 1 }3.14
true
[0, 1, 2, 3, 4, 5]function () { console.log('Hello!'); }
SUBMIT: Primitives (e.g. numbers, strings, booleans, etc.) are immutable values.
QUESTION 5 OF 6
Consider the following:
let string = 'orange';
function changeToApple(string) {
string = 'apple';
}
changeToApple(string);
console.log(string);
// ???
What is logged to the console?
apple
,orange
orange
apple
undefined
SUBMIT: Within changeToApple()
, string
is assigned to 'apple'
. However, this change is only relevant within the function; outside, the value of string
remains 'orange'
.
QUESTION 6 OF 6
Consider the following object,oven
:
const oven = {
type: 'clay',
temperature: 400
};
What is the value ofoven
'stemperature
property after the following operations?
const newOven = oven;
newOven.temperature += 50;
400
50
450
350
SUBMIT: Because newOven
and oven
refer to the same object, increasing the value of newOven
's temperature
property by 50 also increasing that of oven
's.
Summary
Objects are commonly created with literal notation, and can include properties that point to functions called methods. Methods are accessed the same way as other properties of objects, and can be _invoked _the same way as regular functions, except they automatically have access to the other properties of their parent object.
By default, objects are mutable (with a few exceptions), so data within them can be altered. New properties can be added, and existing properties can be modified by simply specifying the property name and assigning (or re-assigning) a value. Additionally, properties and methods of an object can be deleted as well with thedelete
operator, which directly mutates the object.
We've modified objects quite a bit in this section, and even added new methods into them. In the very next section, we'll take a closer look at _invoking _these methods, as well as how these methods can directly access and modify an object itself!
Further Research
- The 'delete' operator on MDN