## Objects

Object properties can refer to numbers, strings, arrays, functions, and other objects. Properties will also accept variables. 

### Creating objects

#### Literal notation - "Object Literal"

Literal objects can have properties and methods added to them on the fly, which we cannot do with a constructor. To add a method to a constructor we must extend its prototype chain.

```javascript
var object = {
    property1: value,
    property2: value
};
```

#### Object constructor

One situation that would make the constructor preferable is the ability to create private variables. Nothing about a literal object is private from what I can tell.

```javascript
var objectName = new Object();
    objectName.property1 = value;
    objectName.property2 = value;
```

##### Custom constructor

```javascript
function Snowboard(brand, model, length) {
  this.brand = brand;
  this.model = model;
  this.length = length;
  this.manufacturer = 'Mervin Manufacturing'; // 'real' snowboards are made by Mervin!

  // define object method
  this.surfLength = function() {
    var feet = Math.floor((this.length * 0.39) / 12).toString();
    var inches = Math.floor((this.length * 0.39) % 12).toString();
    return feet + "\'" + inches + '\"';
  };
}

var bananaHammock = new Snowboard('Lib Tech', 'Banana Hammock', 160);
var billyGoat = new Snowboard('Gnu', 'Billy Goat', 162);

// convert to surf measurement using object method
console.log(billyGoat.surfLength());
```

#### Accessing objects
* __Dot notation__ `ObjectName.PropertyName` - faster to write and clearer to read.
* __Bracket notation__ `ObjectName["Property Name"]` - allows access to properties containing special characters and selection of properties using variables. Bracket notation also take expressions thus enabling dynamic property access. 

```javascript
    for (var i = i, i <= myLibrary["# of Books"]; i++) {
        console.log(myLibrary["book" + i]);
    }
```

* Property values can be changed
    * `billyGoat.length = 164` or using a method `billyGoat.length = billyGoat.length + 2`
    * `billyGoat["length"] = 164`
* Property values can be added to an object
    * `billyGoat.isAwesome = true`
    * `billyGoat["isAwesome"] = true`

```javascript
    // Create book object and add to Library
    function addBook(library, name, writer){
        library["# of Books"]++; // increment w/ each call
        library["book" + library["# of Books"]] = {title: name, author: writer};
    }
    
    addBook(myLibrary, "Great Expectations", "Charles Dickens");
```



### Methods
* Methods are functions associated with objects. 
* Methods can change object property values.
* Methods can make calculations with object properties where functions can only take parameters.
* Methods are called on an object. `ObjectName.methodName()`

#### this
* Keyword `this` acts as a placeholder to refer to the object calling the method.
* Allows reuse of a method for different objects.

When using `this`, the method must be assigned to an object:

```javascript
// unassociated method
var setAge = function (newAge) {
  this.age = newAge;
};
var susan = new Object();
susan.age = 25;
// associate the object with the method
susan.setAge = setAge; 
// call setAge to change value of susan.age
susan.setAge(35);
```
The method can also be assigned to an object explicitly:

```javascript
var rectangle = new Object();
rectangle.length = 3;
rectangle.width = 4;
// method associated with the rectangle object
rectangle.setLength = function (newLength) {
  this.length = newLength;
};
// call setLength
rectangle.setLength(6);
```