Objects


What is an array?


The array is one of the most fundamental data structures. It's an ordered collection of elements. Here's a foo variable, which is assigned to an empty array:

const foo = [];

Each element in an array is referenced by a numeric key called an index, which starts from zero and increments by one for each additional element in the array.

const fruits = ['apple', 'orange', 'kiwi'];

To retrieve the first element in fruits, we access it by its index:

fruits[0]; // 'apple'

To access the last element in fruits if we know the size of the array, we can access it like:

fruits[2]; // 'kiwi'

To access the last element in fruits if don't know the size of the array, we can access it like:

fruits[fruits.length - 1]; // 'kiwi'

Arrays can store elements of any type (from left to right: string, boolean, number, function, object, array)

const mixedArray = ['Marios', true, 27, function() { alert('hello'); }, { name: 'Marios' }, [1, 2]];

What is an object?


Introduction

Objects are unordered collection of associated key/value pairs. Here's a foo variable, which is assigned to an empty object:

const foo = {};

Here's a car variable, which is assigned to an object. Each distinct key-value pair, is known as a property.

const recipe = {
    name: 'Sweet chilli jam',
    difficulty: 'easy',
    vegetarian: true,
    prep: 20,
    cook: 60,
    ingredients: ['red peppers', 'red chillies', 'fresh root ginger', 'garlic cloves', 'cherry tomatoes', 'sugar', 'vinegar']
};

Object creation

To create a new empty object, you can use the literal notation or the constructor function:

const myObject = {}; // Literal notation
const myObject = new Object(); // Ctor function

Object properties


Object property syntax

Object keys are strings and quotation marks surrounding these strings are optional. As a result the following three objects are equivalent.

const person = { age: 12 };
const person = { 'age': 12 };
const person = { 'age': 12 };

Certain situations require the use of quotation marks. Especially if the property name is a reserved word, contains spaces or special characters.

Accessing object properties

To access object properties we use either the dot notation or the bracket notation:

const car = {
    owner: 'Marios',
    color: 'red',
    year: 1990,
    paint: {
        type: 'metallic',
        code: '23fa4567h'
    }
};

Using dot notation we can access car's color property as follows:

car.color; // 'red'

Using bracket notation we can access car's color property as follows:

car['color']; // 'red'

Using dot notation we can access the codeproperty as follows:

car.paint.code; // '23fa4567h'

Using bracket notation we can access the codeproperty as follows:

car['paint']['code']; // '23fa4567h'

The dot notation has its limitations. Consider the following:

const car = {
    owner: 'Marios',
    color: 'red',
    1: 'blah blah blah'
};

const foo = 'color';

car[foo]; // Returns 'red'
car.foo; // Returns undefined

car[1]; // Returns 'blah blah blah'
car.1; // Returns SyntaxError

Considering the following object, write an expression that outputs how to say hello in Portuguese:

const greetings = {
    hello: [{
        english: 'hi',
        french: 'bonjour',
        portuguese: 'oi'
    }],
    goodbye: [{
        english: 'bye',
        french: 'au revoir',
        portuguese: 'tchau'
    }]
};

Solution:

greetings.hello[0].portuguese; // Dot notation
greetings['hello'][0]['portuguese']; // Bracket notation

Modifying object properties

Considering the following object:

const person = {
    name: 'Mario',
    age: 26
}

We can modify the age and name properties as follows:

person.age += 1;
person.name = 'Luigi';

Adding object properties

To add a new property to an object, we simply specify the property name and then giving it a value. We can use both the dot and bracket notation to add properties.

const course = {};

course.IsFree = true; // Dot notation

course['name'] = 'Object-Oriented JavaScript'; // Bracket notation

course.message = function () { // Bracket notation
    alert('Welcome to OO JavaScript. Have fun!');
};

The complete course object now looks like:

const course = {
    IsFree: true,
    name: 'Object-Oriented JavaScript',
    message: function () {
        alert('Welcome to OO JavaScript. Have fun!');
    }
};

Removing object properties

We can go ahead and remove the IsFree property from course using the delete operator. Removing properties with the delete operator returns true upon successful deletion.

delete course.IsFree;

Passing arguments


Passing primitives

In JavaScript primitives (e.g. string, number, boolean) are immutable (meaning they can't be changed).

function foo(n) {
    n = 8;
}

let n = 6;

foo(n);

console.log(n); // n = 6

Passing objects

In JavaScript objects are mutable (meaning they can be changed). Objects are passed by reference.

const foo = {
  color: 'red'
};

function setColor(obj) {
    obj.color = 'blue';
};

setColor(foo);

console.log(foo.color); // blue

When re-assigning an object to a new variable, and then change the copy, changes are also reflected back to the original object since objects are passed by reference.

const original = { color: 'red' };

const copy = original;

copy.color = 'blue';

console.log(original.color); // 'blue'

Comparing objects

The following objects look the same:

const lion = {
    group: 'mammal',
    type: 'carnivor'
}

const tiger = {
    group: 'mammal',
    type: 'carnivor'
}

You might expect the lion and tiger object to be equal but this is not true.

parrot === tiger // false

The expression only returns true when comparing two references to the same object:

const myMammal = lion;
myMammal === lion; // true
myMammal === tiger // false

Object methods


A method is a property of an object whose value is a function.

Consider the following object:

const person = {
    name: 'marios'
}

Consider the following function:

function sayHello () {
    alert('Hello World');
}

If we want to add the sayHello() function into the person object, we can add it with the same way as we add other new properties.

person.sayHello = function () {
    alert('Hello World');
};

The updated person object now looks like:

const person = {
    name: 'marios',
    sayHello: function () {
        alert('Hello World');
    }
};

We can access a method the same way that we do with other properties: by using dot notation or bracket notation.

person.sayHello(); // Dot notation
person['sayHello'](); // Bracket notation

Consider the following object:

const person = {
    name: 'marios',
    favoriteCar: function (model) {
        alert('My favorite car is a ${model}');
    }
}

To pass an argument to the method:

person.favoriteCar('1968 Ford Mustang');

Consider the following array:

const foo = [function sayHello() { alert('Hello');}];

To invoke the sayHello() function:

foo[0]();

So far we've been using anonymous functions for object methods. However, naming those functions is still valid JavaScript syntax:

const person = {
    name: 'marios',
    welcomeMsg: function sayHello() {
        alert('Hello');
    }
};

Whether a method is named or not, it is invoked the same way:

person.welcomeMsg();

'this' keyword


A method can access the object it was called on using this. Using this, methods can access and manipulate an object's properties. this is a reserved word in JavaScript. The value of this can have different meanings outside an object.

Consider the following object:

const car = {
    type: 'RWD',
    identify: function () {
        alert('This car is a ${this.type} car.');
    }
};

When you say this, what you're really saying is 'this object' or 'the object at hand'.

Consider the following object:

const person = {
    name: 'marios',
    age: 26,
    booksRead: ['The Silmarillion', 'The Count of Monte Cristo'],
    ageOneYear: function () {
        this.age += 1;
    },
    addBook: function (book) {
        this.booksRead.push(book);
    }
};

person.ageOneYear();
alert(person.age); // 27

person.addBook('Thinking, Fast and Slow');
alert(person.booksRead[2]); // 'Thinking, Fast and Slow'

Create an object called chameleon with two properties:
1. color, whose value is initially set to 'green' or 'pink'
2. changeColor, a function which changes chameleon's color to 'pink' if it is 'green', or to 'green' if it is 'pink'.

const chameleom = {
    color: 'green',
    changeColor: function () {
        if(this.color === 'pink') {
            this.color = 'green';
        }
        else {
            this.color = 'pink';
        }
    }
};

Globals


const lion = {
    eyes: 2,
    lookAround: fuction () {
        console.log('I see you with my ${this.eyes} eyes!');
    }
};

function whoThis () {
    this.trickyish = true;
}

lion.lookAround(); // 'I see you with my 2 eyes!'

whoThis();

The this keyword inside a method refers to the object the method was called on. In our case this refers to lion.

The value of this inside the regular function is the global window object.

The 'window' object


Introduction

The window object is provided by the browser. This object is not part of the JavaScript specification (i.e. ECMAScript), instead, it is developed by the W3C. This window object has access to a ton of information about the page itself, including:

  1. The page's URL (window.location;)
  2. The vertical scroll position of the page (window.scrollY')
  3. Opening a new web page (window.open('https://www.udacity.com/');)
const car = {
    numberOfDoors: 4,
    drive: function () {
        console.log(`Get in one of the ${this.numberOfDoors} doors, and let's go!`);
    }
};

const letsRoll = car.drive;

letsRoll();

What does you think this refers to in the code above?

Even though car.drive is a method, we're storing the function itself in the a variable letsRoll. Because letsRoll() is invoked as a regular function, this will refer to the window object inside of it.

Properties

Every variable declaration that is made at the global level (outside of a function) automatically becomes a property on the window object. Only declaring variables with the var keyword will add them to the window object. If you declare a variable outside of a function with either let or const, it will not be added as a property to the window object. Similarly to global variables, any global function declaration is accessible on the window object as a method:

var str1 = 'john';
let str2 = 'marios';
const str3 = 'emily';

window.str1 === str1 // true
window.str2 === str2 // false
window.str3 === str3 // false

function learnSomethingNew() {
    window.open('https://www.google.com/');
}

window.learnSomethingNew === learnSomethingNew // true

Considerations

Global variables and functions should be used sparingly. There are actually a number of reasons why, but the two we'll look at are:

  1. Tight Coupling: In tight coupling, pieces of code are joined together in a way where changing one unintentionally alters the functioning of some other code.
  2. Name Collisions: A name collision occurs when two (or more) functions depend on a variable with the same name. A major problem with this is that both functions will try to update the variable and or set the variable, but these changes are overridden by each other.

You should write as few global variables as possible. Write your variables inside of the functions that need them, keeping them as close to where they are needed as possible.

The 'Object()' constructor


const dictionary = {
    mario: 'nfjdfjhdfkdfd',
    john: 'paphos2017',
    mary: 'mary1990',
    ian: 'password'
};
  • Create object: const myObject = new Object();
  • Return object keys: const myArray = Object.keys(dictionary);
  • Return object values: const myArray = Object.values(dictionary);

The resulting array's elements for Object.keys() are strings.

We could also aquire the object's keys and values using a for...in loop like:

const keys = [];
for(const key in dictionary) {
    keys.push(key);
}
Ad1
advertisement
Ad2
advertisement
Ad3
advertisement
Ad4
advertisement
Ad5
advertisement
Ad6
advertisement