An object is like a cabinet with signed files. Every piece of data is stored in its file by the key. key is a string (also called a “property name”), and value can be anything.

An empty object (“empty cabinet”) can be create using one of two syntaxes:

1
2
let user = new Object(); // "object constructor" syntax
let user = {}; // "object literal" syntax

Literals and properties

1
2
3
4
let user = {       // an object
name: "John", // by key "name" store value "John"
age: 30 // by key "age" store value 30
};
1
2
3
// get property values of the object:
alert(user.name); //John
alert(user.age); // 30

To remove a property, we can use the delete operator:

1
delete user.age;

When we write a multiword key name, like:

1
2
3
4
5
let user = {
name: "John",
age: 30,
"like birds": true,
}

We should notice that the dot access doesn’t work for it now:

1
user.likes birds = true // FAULT !!!

This time, we need square bracket notation:

1
2
3
4
5
6
7
8
9
10
let user = {};

// set
user["like birds"] = true;

// get
alert(user["like birds"]); // true

//delete
delete user["likes birds"];

And with sqare bracket notation, we could obtain the property name as the result of any expression - as opposed to a literal string - like from a variable as follows:

1
2
3
4
let key = "likes birds";

// same as user["likes birds"] = true;
user[key] = true;

And then comes this:

1
2
3
4
5
6
7
8
9
let user = {
name: "John",
age: 30
};

let key = prompt("What do you want to know about the user?", "name");

// access by variable
alert(user[key]); // John (if enter "name");

But here the dot notation doesn’t work.

1
2
let key = "name";
alert(user.key) // undefined

Computed properties

We can use square brackets in an object literal, when creating an object. That’s called computed properties.

1
2
3
4
5
6
7
let fruit = prompt("Which fruit to buy?", "apple");

let bag = {
[fruit]: 5, // the name of the property is taken from the variable fruit.
};

alert(bag.apple); // 5 if fruit="apple"

Property value shorthand

We could write this:

1
2
3
4
5
6
7
8
9
10
function makeUser(name, age) {
return {
name, // same as name: name,
age, // same as age: age,
// ...
};
}

let user = makeUser("John", 30);
alert(user.name); // John

The “for..in loop”

1
2
3
4
5
6
7
8
9
10
11
12
let user = {
name: "John",
age: 30,
isAdmin: true
};

for (let key in user) {
// keys
alert(key); // name, age, isAdmin
// values for the keys
alert(user[key]); // John, 30, true
}

Ordered like an object

When we loop over an object, the integer properties are sorted from lower to higher, other then appear in creation order.

For instance:

1
2
3
4
5
6
7
8
9
10
11
let codes = {
"49": "Germany",
"41": "Switzerland",
"44": "Great Britain",
// ..,
"1": "USA"
};

for(let code in codes) {
alert(code); // 1, 41, 44, 49
}

This

1
2
3
4
5
6
7
8
const person = {
name: "Chris",
introduceSelf() {
console.log(`Hi! I'm ${this.name}.`);
},
};

person.introduceSelf(); // Hi! I'm Chris.

The this keyword typically refers to the curren t object the code is being executed in.

Constructors

A constructor is just a function called using the new keyword. When you call a constructor, it will:

  • create a new object.
  • bind this to the nwe object, so you can refer to this in your constructor code.
  • run the code in the constructor.
  • return the new object.

Constructors, by convention, start with a capital letter and are named for the type of the object they create. So we could write our example like this:

1
2
3
4
5
6
7
8
9
function Person(name) {
this.name = name;
this.introlduceSelf = function() {
console.log(`Hi! I'm ${this.name}.`);
};
}

const salva = new Person("Salva");
salva.introduceSelf(); // Hi! I'm Salva.

Differences between objects and primitives

Besides the formal differences, there are also som technical differences which affect how we use each data type. When you define a primitive variable, it will contain a copy of the informatino provided to it.

On the other hand, when you define an object variable, it will contain a reference to the object provided to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let data = 42;
// dataCopy will store a copy of what data contains, so a copy of 42
let dataCopy = data;

// which means that making changes to dataCopy won't affect data itself.
dataCopy = 43;

console.log(data); // 42
console.log(dataCopy); // 43



// obj contains a reference to the object we defined on the right side
const obj = { data: 42 };
// objCopy will contain a reference to the object referenced by obj
const objCopy = obj;

// making changes to objCopy will make changes to the object that it refers to
objCopy.data = 43;

console.log(obj); // { data: 43 }
console.log(objCopy); // { data: 43 }