Objects

CSCI-UA.0480-008

Topics

  • Objects, Object Creation
  • Properties
  • Methods
  • Math Methods
  • Modifying and Deleting Properties
  • Mutability
  • Detecting Properties
  • Looping Over Objects

Types (Again) According to the Specification

The ECMAScript 5 specifications list 6 types, but they're not the ones that typeof returns (of course!):

  • Undefined
  • Null
  • Boolean
  • String
  • Number
  • Object
  • We didn't talk about this, but also… Symbol (ES6)

Ok… So What About typeof?

  1. number
  2. string
  3. boolean
  4. object
  5. function
  6. undefined

Finally - Objects!

We've explored numbers, strings, booleans, undefined and functions a bit, but we haven't really talked about objects yet.

Objects are essentially:

  • an "arbitrary collections of properties"
  • …and their associated values
  • these properties can be added, removed and modified


Can anyone think of analogous types in other languages?

  • HashMaps in Java
  • associative arrays in PHP
  • dictionaries in Python
  • Hashes in Ruby


(ES6 introduces a Map data structure; regular objects have excess baggage, like inherited properties, making them more than just a map)

Creating Objects

Here's an example of an object:


const course = {name:'AIT', section:8, undergraduate:true};

Object literals consist of:

  • surrounding curly braces - {}
    • an empty object is just {}
  • property/value pairs separated by commas - ,
  • properties and values separated from each other with a colon - :
    • properties that aren't valid variables names or valid numbers must be quoted
    • for example: {"still a property name":true}

Object Literals Continued…

Ah, that's better.

Internal white space and newlines won't cause any syntax issues.

  • you could use them for formatting
  • indentation also helps with readability

const course = {
    name:'Applied Internet Technology',
    section:8,
    undergraduate:true
};

Properties

  • properties can be any value, including numbers, strings, and booleans
  • they can also contain other objects… even functions
  • a method is a property that contains a function
  • almost all JavaScript values have properties
    • the only exceptions are null and undefined
    • strings, numbers and booleans act like they have properties
  • which implies that almost everything in JavaScript is an object (or again, acts like an object for some values)!

ES6 Shorthand Property Names

There's also a shortcut to creating properties and values if you already have variables defined.

  • In ES6…
  • creating an object that consists of only variable names
  • will initialize an object with those variable names as properties



const a = 'foo';
const b = 'baz';
const obj = {a, b};
console.log(obj) // { a: 'foo', b: 'baz' }

Accessing Properties

Sooo… how do we access properties? Using our previous object:


const course = {
    name:'Applied Internet Technology',
    section:8,
    undergraduate:true
};

There are two ways to access properties:

  • the dot operator

// gives us 8
console.log(course.section);
  • square brackets

// gives us 8
console.log(course["section"]);

Accessing Properties Continued

Using dot (.) vs using ([]) to access properties:


course.section;
course["section"];
  • when using dot, the part after the dot directly names the property
    • the property name must be a valid variable names. (what were they again? →)
    • start with a letter, underscore ( _ ), or dollar ( $ )
    • following characters can be any of above, and/or digits (0-9)
  • when using square brackets, the part within the brackets is evaluated and is used as the property name
    • this allows for dynamically created property names
    • also allows property names that are not valid variable names obj["I'm ok"] = true (oof, maybe avoid that))

Dynamic Properties

The code below uses brackets for dynamic property access

  1. it asks for user input, specifying a key / property name
  2. and it should output the value at the key

// using the same object from previous slides...
const course = { name:'Applied Internet Technology', section:8, undergraduate:true };

// setting up user input
const readline = require('readline');
const p = readline.createInterface({ input: process.stdin, output: process.stdout });
p.question('Type in an object key\n>', function (resp) {
	// TODO: print value at key
    p.close();
});

Here, we have to use bracket notation: console.log(course[resp]).

Hey Wait…

Let's see some examples of these so called properties (and methods) on some values that we've already seen. Can you recall any?

  • length is a property of both Strings and Arrays

const exclamation = 'wow!';
const listOfExclamations = ['golly!', 'gosh!'];
console.log(exclamation.length, listOfExclamations.length)
  • log is a method of the built-in, global console object

console.log("here's one!")

Methods (Again)

It's worthwhile to repeat that an object property can be a function.

  • if object's property is a function, it's sometimes called a method
  • let's try creating some methods…

const obj = {};
function f() {
    console.log("Hi, I'm a method!");
}
obj.doStuff = f;

const obj = {
    doStuff: function() {
        console.log("Hi, I'm a method!");    
    },
};

const obj = {};
obj.doStuff = function() {
    console.log("Hi, I'm a method!");    
};

ES6 Shorthand Methods

It's pretty common to create methods on objects, so ES6 introduces a shortcut for creating methods on objects simply by setting properties equal to function expressions: →


const obj = {
    f() {console.log('fffff!');},
    g() {console.log('ggggg!');},
};
obj.f();
obj.g();

Contrast this with the ES5 way of creating methods:


const obj = {
  f: function() {console.log('fffff!');},
  g: function() {console.log('ggggg!');},
};

Whew. Back to Objects. The Math One

There are a bunch of built-in objects that are available globally. We've already seen some… like the console object or the isNan() and parseInt functions.

There's also the built-in Math object. It provides a bunch of miscellaneous number crunching methods

  • the usual trig functions like sin, cos, etc.
  • of course, ceil and floor (don't know? let's try →) to round up or down
  • …and the related round
  • random - returns a random number between 0 and 1

Reading, Modifying and Deleting

  • if the property doesn't exist, we'll get back undefined:

// → gives us undefined
console.log(course.nothingToSeeHere);
  • you can assign values to properties by using the = operator:

course.nothingToSeeHere = 'maybe something';
console.log(course.nothingToSeeHere);
  • you can remove properties by using the delete operator:

delete course.nothingToSeeHere;
console.log(course.nothingToSeeHere);

Objects and Mutability

Uh… so what's the implication here regarding objects and mutability?

  • clearly objects are mutable
    • functions are objects; they're mutable too!
    • arrays are objects; they're mutable too (we'll see this again later)!
  • primitives (such as numbers, strings, booleans, null, and undefined) are not, though!

Mutability and References

What will this print out?


const a = {'foo':1, 'bar':2};
const b = a;
b['baz'] = 3;
b.qux = 4;
console.log(a);

{ foo: 1, bar: 2, baz: 3, qux: 4 }

Detecting Properties

Note that if a property doesn't exist, reading that property yields undefined.

Why might this be confusing?

How can we distinguish between a property that actually exists, but is intentionally undefined versus a property that doesn't actually exist?

Detecting Properties Continued

There are two ways to determine if a property actually exists (rather than being undefined by default). Using the course object from before:

  • hasOwnProperty - method on all objects that tests if argument is property of object that hasOwnProperty is called on
  • 
    course.hasOwnProperty('name'); // true
    course.hasOwnProperty('oh no, not here'); // false
    
  • in - an operator that tests if left operand (a string or number) is property of object in right operand… picks up "inherited" properties
  • 
    'name' in course; // true
    'oh no, not here' in course; // false
    


Use hasOwnProperty for now… so you won't have to worry about "inherited" properties.

Looping Over Properties

Use a for (const prop in obj) loop:

  • note that prop can be const declared
  • make sure that you use obj.hasOwnProperty in loop to exclude inherited properties
  • avoid using this kind of loop for Arrays
    • does not preserve order

for (const property in course) {
	if (course.hasOwnProperty(property)) {
		console.log(property +  " is " + course[property]);
	}
}

Some Behind the Scenes

In reality, though, strings, numbers and booleans aren't objects; they're primitives (you know, kind of like Java).

However, as soon as you perform an object-like operation on them, such as a method call:

  • JavaScript creates an actual String, Number or Boolean object that wraps that primitive…
  • and throws it away immediately, once the operations is done
  • this does mean, however, that you can't create arbitrary properties on primitives


See this article on the secret life of JavaScript primitives!

And Finally… JSON

JSON or JavaScript Object Notation is a data storage and communication format based off of JavaScript object literals… but with a few modifications:

  • all property names are surrounded by double quotes
  • values are restricted to simple data: no function calls, variables, comments or computations


Conversion to-and-from JSON can be done using the following methods on the built-in JSON object:

  • stringify(value) - returns a JSON string representation of the value passed in
  • parse(text) - returns an object created from the supplied JSON text
  • for example: JSON.parse("[1, 2, 3]")