The ECMAScript 5 specifications list 6 types, but they're not the ones that typeof returns (of course!):
Undefined
Null
Boolean
String
Number
Object
Symbol
(ES6)We've explored numbers
, strings
, booleans
, undefined
and functions
a bit, but we haven't really talked about objects yet.
Objects are essentially:
Can anyone think of analogous types in other languages? →
(ES6 introduces a Map
data structure; regular objects have excess baggage, like inherited properties, making them more than just a map)
Here's an example of an object:
const course = {name:'AIT', section:8, undergraduate:true};
Object literals consist of:
{}
{}
,
:
{"still a property name":true}
Internal white space and newlines won't cause any syntax issues. →
const course = {
name:'Applied Internet Technology',
section:8,
undergraduate:true
};
null
and undefined
There's also a shortcut to creating properties and values if you already have variables defined. →
const a = 'foo';
const b = 'baz';
const obj = {a, b};
console.log(obj) // { a: 'foo', b: 'baz' }
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:
// gives us 8
console.log(course.section);
// gives us 8
console.log(course["section"]);
Using dot (.
) vs using ([]
) to access properties: →
course.section;
course["section"];
_
), or dollar ( $
) obj["I'm ok"] = true
(oof, maybe avoid that))The code below uses brackets for dynamic property access →
// 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])
.
Let's see some examples of these so called properties (and methods) on some values that we've already seen. Can you recall any? →
const exclamation = 'wow!';
const listOfExclamations = ['golly!', 'gosh!'];
console.log(exclamation.length, listOfExclamations.length)
console.log("here's one!")
It's worthwhile to repeat that an object property can be a function.
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!");
};
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!');},
};
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…
undefined
:
// → gives us undefined
console.log(course.nothingToSeeHere);
=
operator:
course.nothingToSeeHere = 'maybe something';
console.log(course.nothingToSeeHere);
delete course.nothingToSeeHere;
console.log(course.nothingToSeeHere);
Uh… so what's the implication here regarding objects and mutability? →
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 }
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?
There are two ways to determine if a property actually exists (rather than being undefined by default). Using the course
object from before:
course.hasOwnProperty('name'); // true
course.hasOwnProperty('oh no, not here'); // false
'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.
Use a for (const prop in obj)
loop: →
const
declaredobj
.hasOwnProperty in loop to exclude inherited propertiesArrays
for (const property in course) {
if (course.hasOwnProperty(property)) {
console.log(property + " is " + course[property]);
}
}
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:
See this article on the secret life of JavaScript primitives!
JSON or JavaScript Object Notation is a data storage and communication format based off of JavaScript object literals… but with a few modifications:
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 inparse(text)
- returns an object created from the supplied JSON textJSON.parse("[1, 2, 3]")