JavaScript: Crockford on JS Talks

Chapter 2: JavaScript Overview

Objects

Object-orientated language: an object is a dynamic collection of properties.

Every property has a key string that is unique within that object.

get
- object.name // dot notation
- object[expression] // subscript notation

set
- object.name = value;
- object[expression] = value;

delete
- delete object.name
- delete object[expression]

A property is a named collection of values.
value: any JS value
writeable: boolean
enumerable: boolean
configurable: boolean
get: function () { … return value }
set: function (value) { … } 

Object.defineProperty(object, key, descriptor)
Object.defineProperties(object, object_of_descriptors)
Object.getOwnPropertyDescriptor(object,key)
Object.getOwnProperties(object)
Object.keys(object)

Two kinds of properties in the language:
- data properties
- accessor properties (uses get and/or set)

Classes vs Prototypes

Inheritance done using prototypes.

Benefits:
- can simulate the classical language in the prototypal language.
- programs tend to be shorts because don’t need to repeat

Working with prototypical inheritance:
- make an object that you like (object literal or using assignment)
- create new instances that inherit from that object (Object.create)
- customise the new objects
- taxonomy and classification are not necessary

This programming model sometimes called
- delegation: make an object and delegate to another object; or
- differential inheritance: make an object and add only the differences to it

Objects have a prototype attribute (not a property, an attribute of the object)
- prototype: object (reference to prototype) or null (no inheritance)
- Object.create(object, properties...): make a new object which inherits from an object
- Object.getPrototypeOf(object): (shouldn't need to use this- care more what object can do)

new prefix operator

When thinking prototypically, can do everything need to do with Object.create.  Don't need to use new now.

Calling new does this:

function new(func, arguments) {  
  var that = Object.create(func.prototype), result = func.apply(that, arguments);
  return (typeof result === 'object' && result) || that;
}

If forget to call new on the constructor, the constructor will hammer the global object which is a hazard (fixed in ES5/strict).  So don't need to use new anymore with ES5.

Solutions to problems with JS in ES5

Object.create(null) creates an object that does not inherit anything.
Set the enumerable attribute to false when adding methods to prototypes. That keeps them out of for in enumerations.
Object.keys(object) produces an array of strings, the keys of the own (not inherited) properties only

Keys must be strings

Objects have an extensible attribute is ES5

extensible: boolean
Object.preventExtensions(object)
Object.isExtensible(object)
Object.seal(object)
Object.isSealed(object)
Object.freeze(object)
Object.isFrozen(object)

Every type inherits from Objects: Number, Boolean, String, Array, Date, RegExp, Function

Numbers

- only one type of number in JS: 64-bit floating point and no integers
- compares to C for instance where have many types of numbers, in order to save memory given early memory constraints
- decimal fractions are approximate: convert to integers first (e.g. convert to cents) and then do work
- all Numbers inherit from Number.prototype, can therefore create Number methods: don't want to do this carelessly because Number.prototype in global scope and available to all programs that are running on the same page.

Numbers are first class objects:
- a number can be stored in a variable
- a number can be passed as a parameter
- a number can be returned from a function
- a number can be stored in an object

Math object: inherited from Java - should have been methods of Number but in own object

NaN
- special number: Not a Number (the number that isn't any real number)
- can be the result of undefined or erroneous operations (i.e. 0/0 results in NaN)
- toxic: any arithmetic operation with NaN as in input will have NaN as a result
- NaN is not equal to anything, including NaN
- NaN === NaN is false
- NaN !== NaN is true

Boolean

Boolean is a type named after mathematician George Boole:
- two values: true and false

Strings

Nobody knows why a sequence of characters are called strings in any programming
- a sequence of 0 or more 16-bit Unicode characters
- JS has no awareness of surrogate pairs (extra UTF-16 characters)
- no separate character type (i.e. no char - characters are just a short string with length 1)
- strings are immutable (i.e. they're frozen: once a string is created, it is not possible to modify it. However, it is still possible to create another string based on an operation on the original string.)
- similar strings are equal ===
- string literals can use single or double quotes with \ escapement

Multiline string literals will syntax error if have a space after the \
var long_line_1 = "This is a \
long line";
// ok
var long_line_2 = "This is a \  long line"; // syntax error

Convert numbers to a string
str = num.toString(); // number toString method
str = String(num); // String function (this one will work with null and undefined)

Convert a string to a number
num = Number(str); // the Number function
num = +str; // + prefix operator

parseInt(str, 10) // the parseInt function converts the value into a number. It stops at the first non-digit character: parseInt("12cm") === 12

The radix (10) should always be used (fixed in ES5/strict):
parseInt("08") === 0
parseInt("08", 10) === 8

String.length
Strings are objects, objects can have properties.  One of the properties of a string is its length.
- the length property determines the number of 16-bit characters in a string
- extended characters are counted as 2

Arrays

In other programming languages, an array is an contiguous sequence of memory divided into equal sized slots.  Given an index number can compute which slot you're in and get the value back. Array is the fastest of all data structures.

In JS, an array is an object that simulates an array.
- Array inherits from Object
- a lot of overhead in JS.  Indexes are converted to strings and used as names for retrieving values: take an index, turn it into a number, stick it into an object, does hash operation, figures out what bucket to put it in, creates a property. Every time access a field in the object, having to do a hash lookup.
- therefore, speed advantages that would like to have with arrays are not present
- very efficient for sparse arrays (but these not used in web applications)
- not very efficient in most other cases
- one advantage: no need to provide a length or type when creating an array

Array.length
- unlike objects, arrays have a special length property
- it is always 1 larger than the highest integer subscript (1 more than the last property in the array)
- it allows use of the traditional for statement

for (i = 0; i < a.length; i +=1) {  
    ...
}

- do not use for in with arrays (because does not guarantee what order its going to bring the items out)

Array Literals
- an array literal uses []
- can contain any number of expressions, separated by commas
- new items can be appended: myList[myList.length] = 'new item';
- the dot notation (myList.3) should not be used with arrays (compiler can't differentiate from numbers). Need to use subscript notation.

Array.sort(); will treat elements as strings which can provide unusual results

Deleting Elements
delete array[number] // removes the element but leave a hole in the number

array.splice(number, 1) // removes the element and renumbers all the following elements. Splice is not fast because has to reassign keys and clean up hash

myArray = ['a', 'b', 'c', 'd'];
delete myArray[1]; // ['a', undefined, 'c', 'd']
myArray.splice(1, 1); // ['a', 'c', 'd']

Arrays vs Objects

- use objects when the names are arbitrary strings
- use arrays when the names are sequential integers
- don't get confused by the term Associative Array.  In JS, Object is the Associative Array.

Date

The data function is based on Java's Date class.  It was not Y2K ready.

RegExp

Great for matching simple patterns, but for complicated stuff does not scale well.

Functions

Coming up next chapter

null and undefined

All values are objects, except null and undefined.

null
- a value that isn't anything: value you give something when you don't have anything else to say about it

undefined
- a value that isn't even that
- the default value for variables and parameters
- the value of missing members in objects (i.e. if query on object and it isn't there, object will return undefined)

typeof

typeof prefix operator returns a string identifying the type of a value

type | typeof
--- | --- object | 'object'
function | 'function'
array | 'object' // can use Array.isArray() (returns true if array, otherwise false)
number | 'number'
string | 'string'
boolean | 'boolean'
null | 'object'
undefined | 'undefined'

Falsy and Truthy values

These values are considered falsy:
- false
- null
- undefined
- "" (empty string)
- 0
- NaN

All other values (including all objects, "0" and "false") are truthy.

Truthy means if put into the control part if an if statement, will then take the then branch. Falsy means will take the else branch.

Loosely Typed

- any of the types can be stored in a variable, or passed as a parameter to any function
- the language is not "untyped"

Reference

Objects can be passed as arguments to functions, and can be returned by functions:
- Objects are passed by reference (gets a reference to the function - almost never copied)
- Objects are not passed by value

The === operator compares object references, not values
- true only if both operands are the same object

C

JS is syntactically a C family language. It differs from C mainly in its type system, which allows functions to be values.

Operators

Any truthy value can be converted to boolean with !!value

Bitwise operators convert the operand to a 32-bit signed integer, and turn the result back into a 64-bit floating point

& | ^ >> >>> <<

Throw statement

throw new Error(reason);

throw {  
  name: exceptionName,
  message: reason
};

With statement

Don't use the with statement. Removed in ES5 strict.

Act III: Function

The best part of JS: functions are where the power and the beauty is. Other languages have methods, classes, constructors and modules.  In JS, that's functions and more.

function expression

- function
- optional name
- parameters: wrapped in params, zero or more names, separated by ,
- body: wrapped in curly braces, zero or more statements

Functions produce an instance of a function object.  Function objects are first class:
- may be passed as an argument to a function
- may be returned from a function
- may be assigned a variable
- may be stored in an object or array

Function objects inherit from Function.prototype.

var statement

- declares and initialises variables within a function
- types are not specified
- a variable declared anywhere within a function is visible everywhere within the function

var statement gets split into two parts:
- the declaration part gets hoisted to the top of the function, initialising with undefined
- the initialisation part turns into an ordinary assignment

var myVar = 0, myOtherVar; expands into:

var myVar = undefined,  
  myOtherVar = undefined;
  ...

  myVar = 0;

function statement

- function
- mandatory name
- parameters: wrapped in parens, zero or more names, separated by ,
- body: wrapped in curly braces, zero or more statements

Confusing to have both function expressions and function statements.  The function statement was the older thing while the function expression which is more useful form came later.

Function statement expands into a var statement which creates a variable and assigns a function value to it.

function foo() {}  

expands to:

var foo = function foo() {};  

expands to:

var foo = undefined;  
foo = function foo() {};  

The assignment of the function is also hoisted.

function expression vs. function statement

If the first token in a statement is function, then it is a function statement.

For example, can't put a function statement inside an if statement because of the hoisting.

Scope

Most other C syntax languages have {block} scope (block scope doesn't work because vars get hoisted).  JS has function scope.

- only functions have scope
- variables defined in a function are not visible outside of the function. But they are visible everywhere inside that function.
- therefore, can't have for loops inside for loops with var = i, because inner loop will continually reset outer for loop.

Recommendations due to hoisting:
- declare all variables at the top of the function
- declare all functions before you call them

Return statement

Allows function to return early, or return expression:
return expression;
or
return;

- if there is no expression, then the return value is undefined
- except for constructors, whose default return value is this (the new object that you're constructing)

Two pseudo parameters

There are two pseudo parameters that every function can receive.

arguments
- when a function is invoked, in addition to its parameters it also gets a special parameter called arguments - it contains all of the arguments from the invocation
- it is an array-like object (but not an array)
- arguments.length is the number of arguments passed
- weird interaction with parameters
- highly recommends treating as a read only data structure
- inherits from Array.prototype

this
- the this parameter contains a reference to the object of invocation
- this allows a method to know what object it is concerned with
- this allows a single instance of a function object to service many functions
- this is the key to prototypal inheritance

Invocation

- the ( ) suffix operator surrounding zero or more comma separated arguments
- the arguments will be bound to the parameters of the function
- if a function is called with too many arguments, the extra are ignored
- if a function is called with too few arguments, the missing values will be undefined
- there is no implicit type checking on the arguments

4 ways to call a function:

Function form
functionObject(arguments)

Method form
thisObject.methodName(arguments)
thisObject['methodName'] (arguments)

Constructor form
new FunctionObject(arguments)

Apply form
functionObject.apply(thisObject, [arguments])
functionObject.call(thisObject, arguments)

Function form

- this is set to the global object in ES3.  In ES5/strict this is bound to undefined.
- an inner function does not get access to the outer this. A solution is to assign this in the outer function:
var that = this;

Method form

- this is set to thisObject (this object containing the function)
- this allows methods to have a reference to the object of interest

Constructor form

- a new object is created and assigned to this
- if there is not an explicit return value, then this will be returned
- used in the pseudoclassical style

Apply form

- allows for calling the function, explicitly specifying thisObject

this

- the value of 'this' depends on the calling form.
- 'this' gives methods access to their objects
- 'this' is bound at invocation time

Invocation form | this
---|---
function | undefined
method | the object
constructor | the new object
apply | explicit argument passed in

Functions generally

Where did functions come from?
- subroutine: from assembly era
- call & return idea
- aka in other languages: sub, procedure, proc, func function, lambda

Motivations for subroutines are code reuse (divide and conquer), modularity (between programs), expressiveness, higher order (do with functions that which couldn't otherwise)

Higher order idea lead to recursion:
- recursion is when a function calls itself, or is defined in terms of itself (not possible in Fortran for example).

Recursion can be lead to become a better programmer.
For example, the Quicksort:
- divide the array into two groups, low and high
- call Quicksort on each group container more than one element

Closure

Sometimes called lexical scoping, or static scoping.

The context of an inner function includes the scope of the outer function. An inner function enjoys the context even after the parent functions have returned.  One functions closes over the variables of an inner function.

Closures make JS a brilliant programming language.

Slow example
In circumstances where names is large this is slow because array is created every time function is called.

var digit_name = function (n) {  
  var names = ['zero', 'one', 'two', 'three', 'four', 'five']; // would be global var if assigned outside this function

  return names[n];
};
alert(digit_names(3)); // 'three'  

Closure example
IIFE: function is immediately invoked function expression.  The whole function is not stored in digit_name, rather the function that is returned. Faster because array is not created every time. The ultimate params is a clue to the reader but not required by the language.

var digit_name = (function () {  
  var names = ['zero', 'one', 'two', 'three', 'four', 'five'];
  // returned function is assigned to digit_name because IIFE
  return function (n) {
    return names[n];
   };
}());
alert(digit_names(3)); // 'three'  

'this' is not captured in closure.

Pseudoclassical Inheritance

The inheritance scheme designed for the language. Crockford doesn't care for it.

function Gizmo (id) {  
  this.id = id;
}
Gizmo.prototype.toString = function () {  
  return "gizmo " \+ this.id;
};
function Hoozit (id) {  
  this.id = id;
}
Hoozit.prototype = new Gizmo(); // replace Hoozit's prototype with new instance of Gizmo  
Hozit.prototype.test = function (id) {  
  return this.id === id;
};

Prototypal Inheritance - Crockford's style

New definer of gizmo, pass Object because want gizmo to inherit from global object, pass the constructor function, and pass an object containing the methods that it should add to its own prototype.

var gizmo = new_constructor(Object, function (id) {  
  this.id = id;
}, {
  toString: function () {
    return "gizmo " \+ this.id;
  }
});
// pass in gizmo because want hoozit to inherit from gizmo, pass the constructor function, and pass object containing methods to add to its prototype.

var hoozit = new_constructor(gizmo, function (id) {  
  this.id = id;
}, {
  test: function (id) {
    return this.id === id;
  }
});
function new_constructor(extend, initialiser, methods) {  
   // create the prototype object by calling Object.create
  var func, prototype = Object.create(extend && extend.prototype);

  if (methods) {
    // call keys methods, to return array of all the own keys, array has forEach method to copy all of the keys into the prototype
    methods.keys().forEach(function (key) {
      prototype[key] = methods[key];
    });
   }

  // func to make hoozits - does the same thing as new.
  func = function () {
    var that = Object.create(prototype);
    if (typeof initialiser === 'function') {
      initialiser.apply(that, arguments);
    }

    return that;

  };

  func.prototype = prototype;
  prototype.constructor = func;

  return func;

}

Module Pattern

Avoid creating global variables to minimise conflicts can create.

Create singleton object - only one instance of. Don't assign function, but consequence of calling that function.  Closure allows methods returned to share variables of parent function:

var singleton = (function () {  
  var privateVariable;

  function privateVariable (x) { 
    ... privateVariable ...
  }

  return {
    firstMethod: function (a, b) {
      ... privateVariable ...
    },
    secondMethod: function (a, b) {    
      ... privateVariable () ...
    }
  };
}());

Module pattern can easily be transformed into constructor pattern
1. Make an object
- Object literal
- new
- Object.create
- call another power constructor
2. Define some variables and functions
- the become private members
3. Augment the object with privileged methods (a method which closes over the private state - has access to the private state)
4. Return the object

Functional Inheritance

function gizmo (id) {  
  return {
    id: id, // can remove id if needed for privacy
    toString: function () {
      return "gizmo " \+ this.id;
    }
  };
}
function hoozit (id) {  
  var that = gizmo(id);
  that.test = function (testid) {
    return testid === this.id;
  };
  return that;
}

Don't declare functions in a loop:
- it can be wasteful because a new function object is created every iteration
- it can be confusing because the new function closes over the loop's variables, not over their current values

Episode IV: Ajax

Runoff (MIT in 1960s): lines starting with . contain commands, lines without contain pure text. This lead to GML (generalised markup language). Brian Reid's Scribe: first separation of structure and presentation for documents.

Ultimately these inspired HTML.  HTML was not state-of-the-art when it was introduced.   It was intended for simple document views, it was not intended to be an application platform.  The web standards were grown from a naive hypertext system under intense, highly unstable competitive pressure.

Five problems with css: lack of modularity; selector management is complicated; declarations are too weak for modern web applications; not intended for dynamic content; it is unimplementable, all about the quirks.

JavaScript what kept the browser and web alive despite failings.

The Document Object Model

- the DOM
- the browser's API: the interface the browser provides to JavaScript for manipulating documents
- design and development: Brendan Eich (Netscape) influenced by book on HyperCard, Scott Isaacs (Microsoft)
- in original Netscape model not all elements were scriptable. In Microsoft model all elements are completely scriptable

Browser

Mosaic browser added image tags.  Mosaic which would go back to fetch before continuing parsing.  Netscape parse engine added a placeholder at the image, would start to fetch the image, but parse would continue on. Would keep doing this for whole document fetching images. User experience of seeing text first much better than Mosaic.

Scripted Browser

This led to event model.  Event is fired (touching form, operating system etc). Causes script to run to completion: every event associated with a script. In process of running may mutate the document tree (page). This causes re-flowing and re-painting.

Bear in mind, some scripts can cause flow to start immediately without script completing. For example, text in span- ask how pixels wide are you?

Document.write: allows script insertion of text

Where insert a script can have huge impact on load time:
- place script tags as close to the bottom of body as possible (and css as high as possible)
- minify and gzip script files
- reduce number of script files as much as possible

Document Tree Structure of HTML from early IE

At root of the tree is the document node. In the browser, there is a global variable called document, which is a variable containing document node.  In this example, there is a HEAD node, but no head in the document (some added by default).

document.documentElement refers to HTML.  W3C hoped at some point to replace HTML so gave a vague reference.  But refers to HTML.

Walk the DOM

Recursive function to visit every node in a tree (or sub-tree) in the same order that will be displayed.

Pass in node to start with, and function that will be called for each visit:

function walkTheDOM (node, func) {  
  func(node);
  node = node.firstChild;
  while (node) {
    walkTheDOM (node, func);
    node = node.nextSbling;
  }
}

Retrieving Nodes

document.getElementbyId(id)
document.getElementsbyName(name) // return node lists
node.getElementsbyTagName(tagName) // return node lists

Events

The browser has an event-driven, single-threaded, asynchronous programming model.
- events are targeted to particular nodes
- events cause the invocation of event handler functions

node.addEventListener(type, f, false);

Performance

- touching a node has a cost
- styling can have big cost (has to search through the cascade)
- reflow can have a big cost
- repaint can have a big cost
- random things like nodelist can have a big cost
- in most applications, JS has a small cost.  Most cost is in the DOM.

Must optimise with good data to understand where the cost is being paid.

Ajax

With Ajax libraries, the source of innovation shifted from the browser makers to the web developers.

What you get with AJAX library:
- portability
- correction
- model
- widgets

Client and Server middle ground

Seek the middle way between client and server: don't ask google for results and get everything from server at once.  Server will only send 10 results.  So need a dialogue between the two.

Part 5: The End of All Things

The Browser and Security

Cross-site Scripting (XSS) attack
- confusion of interest attack

What can attacker do if he gets some scripts onto your page? (HTML or script that creates a script tag):
- an attacker can request additional scripts from any server in the world: once it gets a foothold, it can obtain all the scripts it needs
- an attacker can read the document: the attacker can see everything the user sees
- an attacker can make requests of your server.  If connection over SSL, attacker gets access to SSL connection.  The server cannot detect that the request did not originate with your application.
- if your server accepts SQL queries, then the attacker gets access to your database
- an attacker has control over the display and can request information from the user: the user cannot detect that the request did not originate with your application
- an attacker can send information to any server in the world
- the browser does not prevent any of these.  Web standards require these weaknesses.

JS is Pass by Reference

Don't confuse variables with values.

Will alert true only if a and b are the same object, will be false if identical objects.  Alerts true: a and b are not copies of the variable, they are the value that the variable references:

variable = {};  
a = variable;  
b = variable;  
alert(a === b);  

Will alert {} because passing to funky the value that x had, we're not passing it x.  Funky knows nothing about x, only knows that passed an object. Therefore, the assignment of o happens completely independently of x.

function funky (o) {  
  o = null;
}
var x = {};  
funky(x);  
alert(x);  

System design

David Parnas: On the Criteria to Be Used in Decomposing Systems into Modules (1972)
- information hiding on a need to know basis.  Only given an element everything it needs and nothing more.
- a reference is capability, so capability hiding on need to know basis.

There are three ways only to obtain reference in an object capability security system, and by no other means:

1. By creation:
- if function creates an object it gets reference to that object

2. By construction:
- an object may be endowed by its constructor with references. This can include references in the constructor's context and inherited references

3. By introduction:
- A has a reference to B and C
- B has no references, so it cannot communicate with A or C
- C has no references, so it cannot communicate with A or B

If A wants to introduce, A calls B, passing a reference to C as a parameter.

Now B has a capability to communicate/interact with C

JS is not yet a capability language, because it depends on a global object. If references can be obtained in any other way besides by creation, by construction or by introduction, we do not have a safe system.

Performance

Important to think about optimising your optimising: meta optimising.

total time = cost per iteration * number of iterations

Bad Parts: (global) Object

- it is a container for all global variables and all built-in objects
- on browsers (the DOM), window is the global object
- need to tame or eliminate global object

Bad Parts: Implied Global

- any variable not properly declared is assumed to be global by default
- this makes it easy for beginners, but applications less reliable
- this may contain global variable i

for (i = 0; i < n; i += 1) { ... }

Global variables should be as rare as hen's teeth and stick out like sore thumbs: ALLCAPS (rather than allcaps for constants)

Bad Parts: ++, with statement

Programming styles should be conventions that promote good tradeoffs: avoidance of ambiguity, confusion and potential errors.

Scene 6: Loopage

Browser Event Loop

- event queue containing callback functions (timer, ui, network)
- turn: remove one callback from the queue. It runs to completion
- Prime directive: never block, never wait, run fast
- the event loop is one of the best parts of the browser
- avoid: alert, confirm, prompt, XHR synchronous

Read / Write & I/O

Early machines up to IBM's FORTRAN: stop the program until the I/O operation completed and then resume.

Timesharing relied on this timesharing: once program was blocked could take the next.

Virtually all programming have blocking I/O: READ / WRITE. Except C, which has no I/O at all (although it came with stdio - standard io).

Hypercard on Macintosh was all about events, and writing event handlers. The program (a stack) was event handlers that bubble up.

JS does not have READ: READ blocks, and blocking is bad for event loops.

Event loop is one approach to concurrency: most common is threading.

JavaScript on the Server

Not a new idea: Netscape offered an SSJS product in 1996. Node implements a web server in a JS event loop: its a high-performance event pump.

Node has some synchronous functions that do block. Also, require blocks which is used for loading scripts.

Level 7: ECMAScript 5

"Any change to a standard is an act of violence."

1999: ES3
2009: ES5
- Default
- Strict
Work with ES5/Strict (avoid ES5/Default)

Goals of ES5: don't break the web, improve the language for the users of the language, third party security (mashups), no new syntax.

Getter and setter added

Get syntax binds and object property to a function that will be called when that property is looked up. Set syntax binds an object property to a function to be called when these is an attempt to set that property.

function make_temp (temp) {  
  return {
    get celsius () {
      return temp;
    },
    set celsius (value) {
      temp = value;
    }
  };
}

Fixes

multiline string literals:
"this is a \ long ling" //no space allowed at the end of the line
Constants: infinity, NaN, undefined
ParseInt no longer requires radix
Regexp Literals /regexp/ now produces new regular expression objects every time

Brand New Methods added

Crockford test to see if method already exists:
if (!Function.prototype.hasOwnProperty('bind'))

JSON now standard equipment (json2 library)
JSON.parse(text, reviver)
JSON.stringify(value, replacer, space)

Function.prototype.bind allows you to create methods where expect a callback.
String.prototype.trim remove excess white space from the end

Array methods on each element of the array:
Array.prototype.every as long as true, will keep going
Array.prototype.filter adds true to new array
Array.prototype.forEachcalls a function for each element
Array.prototype.indexOffind an element in an array based on its value
Array.prototype.lastIndexOf same as indexOf but from end
Array.prototype.map: like forEach, but forEach that comes back its put in an arry
Array.prototype.reduce calls a function for each and passes an argument for the next
Array.prototype.some inverse of every
Date.now()
Date.prototype.toISOString support for ISO dates
Object.keys given an object, returns an array of all enumerable keys
Object.create makes new object which inherits from old object
Array.isArray figure out if value is an array, returns true true

Meta Object API: control over the attributes of the properties of the objects
Objects have properties (aka members, methods, elements). Properties have attributes but used to be invisible. Now can have access.
Two kinds of properties:
1. Data properties: have a value that can set and retrieve
value: any JS value
writeable: boolean
enumerable: boolean
configurable: boolean

var my_object = Object.create(Object.prototype);  
Object.defineProperty(my_object,  
  'foo', {
     value: bar,
     writeable: true,
     enumerable: true,
     configurable: true
}); 

2. Accessor properties: have get / set on them - just associate to function
get: function () { … return value }
set: function (value) { … } 

Strict Mode

Opt-in to removing bad parts. Add pragma to first line of file or first line of function. Best to use function form:
- 'use strict';
- new reserved words: implements, interface, let, package, private, protected, public, static, yield
- no more implied global variables within functions
- this is not bound to the global object by function form
- apply and call do not default to the global object
- no with statement
- setting a writeable: false property will throw
- deleting a configurable: false property will throw
- restrictions on eval
- eval and arguments are reserved words
- arguments no linked to parameters
- no more arguments.caller or arguments.callee
- no more octal literals
- duplicate names in an object literal of function parameters are a syntax error

Outcomes:
- forgetting to use the new prefix will now throw an exception, not silently clobber the global object

Section 8: JS Programming Style & Your Brain

The Science of Fear by Daniel Gardner
We misunderstand what danger is and end up fearing the wrong things. Because we fear the wrong things, we put ourselves in greater danger.

Two systems in the brain:
- Head: analytical thinking, arithmetic and mathematics. Its good, but the head is slow to think (why we invented computers)
- Gut: evolved from flight or fight response. Very fast, tradeoffs to speed: bias is set that its okay to get false positive because better than a slow positive. Not solving hard problems, just looking for certain patterns; when sees those patterns it reacts.

Connection between two systems: gut informs the head. Gut sets up the assumptions that the head will use in its computation.  However, head not aware of that, and the weight head gives to gut more than what head has experienced.

Programming uses Head and Gut
- gut bad for making tradeoffs

Style

Guidelines:
- JSLint.com
- If there is a feature of a language that is sometimes problematic, and if it can be replaced with another feature that is more reliable, then always use the more reliable feature.
- Avoid forms that are difficult to distinguish from common errors.
- Write in a way that clearly communicates your intent.
- For no cost, by adopting a more rigorous style, many classes of errors can be automatically avoided
- Designing a programming style demands discipline: not selecting features because they are liked, or familiar.

Spaces:
Use spaces to disambiguate parens. Put a space to indicate grouping and no space to indicate invocation.

Wrong:
- foo (bar); // no space because invoking a function
- return(a+b); // space because not a function

IIFE:
- place ( ) around entire invocation

Semi-colons:
- never rely on automatic semicolon insertion

Broken equals:
- always use === equal because reader can't tell if using == in rare case it works or whether incompetent code

Functions:
- declare all variables at the top of the function (because of function scope and hoisting)
- declare all functions before you call them
- be particularly mindful of var i in for statement: its scoped to function for statement sits in

Global variables:
- global variables are evil, avoid them
- when using global variables, be explicit: UPPERCASE
- global variables should be as rare as hens teeth and stick out like a sore thumb
(not to be confused with C convention that had all macros in UPPERCASE)

Object.create instead of new prefix because if use the clause without new, will clobber global variables (although fixed in ES5/strict).

Constructor functions should be named with InitialCaps. Nothing else should be named with InitialCaps.

Don't use ++, use x += 1