I read JavaScript Enlightenment by Cory Lindley over the weekend. It was the perfect thing for me right now, as an advanced beginner. It really breaks down all the parts of tha langauge in an understandable way. I feel like I get the ‘big picture’ much better after having read it. Here are some notes I took along the way.
Explanations
Objects
In javascript, object is king. An object is a set of properties with keys and values.
1 2 3 |
|
Javascript’s Native Object Constructors
These are the nine object constructors built into JavaScript:
- Number()
- String()
- Boolean()
- Object()
- Array()
- Function()
- Date()
- RegExp()
- Error()
There’s also Math, which is not a constructor. It acts like an instantiated object.
Thus, you can do:
1
|
|
But NOT:
1
|
|
Contructors & Instantiating With Constructors
Every object can be built with a constructor. You instantiate the object with the ‘new’ keyword.
Here’s the syntax:
1
|
|
You can also define your own constructors, like this:
1 2 3 4 5 6 7 |
|
Object Literal Notation
Instead of using the new keyword, you can create an object with the literal syntax:
1 2 3 4 5 6 7 8 |
|
* These tjree literals do NOT return an object, but a Javascript primitive. Their constructors DO return objects. A primitive is an irreducible value. If they are later treated as an object, for example by calling a method on them, they are temporarily wrapped in an object.
The Third Notation
Another way to create a primitive (does not use the new keyword):
1 2 3 |
|
Complex Objects
Objects that contain multiple values, which can be primitives or other complex objects. These are objects created created with the new keyword, or literal notation (and are NOT one of the primitives).
They are also known as “composite objects” or a “reference types”. These objects store an address reference to an object. If you copy them, the copies are also references to the same address. Therefore, they will all mutate if the object is changed.
1 2 3 4 5 |
|
Complex Objects - Native Properties
‘constructor’
In addition to their basic property keys, all instantiated objects have a property called ‘constructor’.
1 2 3 |
|
‘instanceof’
The type of an instantiated object can be checked with ‘instanceof’.
1 2 3 |
|
Instance Properties
Instances of a constructor can be given their own properties. This includes objects created from the nine native constructors, but does not include primitives.
1 2 3 4 |
|
1 2 3 4 |
|
Accessing Properties
Dot notation vs. Bracket notation:
1 2 |
|
Bracket notation has two advantages: it can be used to concatenate strings in the property name, and it can use reserved words.
1 2 3 4 5 6 7 8 9 10 11 |
|
Deleting Properties
There is only only way to delete a property, which is to use the delete keyword. Setting it to null or undefined will not remove it.
1
|
|
hasOwnProperty()
This method can be used to check if a property belongs to a given object. It may return false when an object’s constructor does have the property; it only tells whether the object itself has the property.
The Prototype Property
All instances of a constructor contain this property. The properties of the ‘prototype’ property itself are inherited by instances of the constructor. Object.prototype is at the top of the inheritance chain, so all objects inherit from it. It is a very bad idea to change Object.prototype’s properties.
The ‘in’ Keyword
Checks for a property in an object. Similar to hasOwnProperty(), but it does look up the inheritance chain.
1 2 3 |
|
Inheritance and Looping
If you run a for/in loop on the properties of an object, it will return inherited properties unless you use a guard clause checking each property with hasOwnProperty().
Host Objects
These objects are provided by the JavaScript environment. Examples include ‘window’ and ‘document’ in the browser.
The ‘this’ Keyword
The ‘this’ keyword is available within the scope of a function, but it refers to the object which called the current function. It does not refer to the function itself, but its containing object.
‘this’ acts like any other variable, only it can’t be modified.
In EcmaScript 3, calling ‘this’ from a nested function referred to the Head Object. This was a serious mistake that was fixed in ES5. As a workaround, programmers used a variable ‘that’ to keep track of the value of ‘this’ inside of nested functions.
‘this’ can be overridden with call() and apply(), which redefine ‘this’ to be their first parameter (the object they are targetting).
When using a constructor to create an instance, ‘this’ refers to the object-to-be (the instance that has not yet been created). This pattern works for both properties and methods.
1 2 3 |
|
Scope
There are three kinds of scope in JavaScript:
- Global Scope
- Function Scope
- Eval Scope
There is no scope created by ‘for’ or ‘while’ loops, nor by ‘if’.
If a variable is declared without the keyword ‘var’, it is created in the global scope. This is to be avoided.
1 2 |
|
Lexical Scoping
Objects can look up the inheritance chain to find properties, functions, and methods, but they cannot look into their childrens’ scopes. When looking for a value up the inheritance chain, the first found value is returned. Any values in higher scopes are ‘shadowed’, or ‘masked’ by the value found in the lowest scope.
Priority of inheritance is defined in the definition (the code), not the state of objects at the time of invocation.
Prototype
Prototype is a property found in instances created by the Function() constructor. These functions can be used as constructors themselves.
Why should you care?
- Prototype is what the nine native constructors use to pass methods to their object children.
- You can use prototypes to orchestrate inheritance.
- You may inherit code that uses it.
- It’s efficient in that all instances of an object can share a method defined in only one place: the prototype object.
The prototype property is basically a container (an object) for properties and methods you want instances of a given object to inherit. They will inherit the current value of the property (it is updated dynamically).
The values passed into prototype must be complex (not JavaScript primitives).
Instances of an object access the prototype’s host object with their ‘constructor’ property.
1 2 3 4 5 6 7 8 |
|
All objects have a common highest ancestor: Object.prototype. Overriding the ‘prototype’ property on Object will break its functionality.
The Parts of JavaScript
The Head/Global Object
This object represents the highest scope in a given JavaScript environment. In the browser, it is ‘window’. It contains ALL objects in the environment.
Global properties and variables are contained in the Head Object, and are accessible from any other scope through inheritance.
The Head Object can be referenced by referring to ‘window’, or using the keyword ‘this’ from the global scope. Thus, its scope is implied from outside of a function.
1 2 3 |
|
Global Functions
These are provided by the environment.
- decodeURI()
- decodeURIComponent()
- encodeURI()
- encodeURIComponent()
- eval()
- isFinite()
- isNaN()
- parseFloat()
- parseInt()
Object()
Gives an empty object container. Creating objects with a literal is the preferred syntax.
Parameters
Object() takes a parameter that is a value. It is null/undefined by default.
Properties and Methods
Note: ALL JavaScript objects inherit the following properties and methods from Object.prototype.
When defining property keys, one can use dot notation or bracket notation. Bracket notation is more flexible, because it allows for the use of concatenation and reserved words.
Properties
- prototype
Instance Properties
- constructor
Instance Methods
- hasOwnProperty()
- isPrototypeOf()
- propertyIsEnumerable()
- toLocaleString()
- toString()
- valueOf()
Function()
Functions always return a value. This will be ‘undefined’ if another return value is not specified.
Functions define a new scope. Variables within it cannot be seen from objects containing the function, but they can be seen by objects it contains. This is called ‘lexical scoping’.
There are three ways to define a new function:
- With the constructor: var myFunction = new Function(){};
- With a literal, as an expression: var myFunction = function(){};
- With a literal, as a statement: function myFunction(){};
Functions are ‘first class citizens’ in JavaScript. They are objects, they can be stored, they have properties, and they can be passed into other functions (higher-order functions).
Invoking Functions
Functions are invoked with (). This can be done in three ways:
- As a function - func();
- As a method - when attached to an object - myVar.func();
- Using apply() or call()
- As a constructor:
1 2 3 |
|
Anonymous Functions
Functions not given an identifier are anonymous.
1
|
|
Self-Invoking Functions
Functions that call themselves immediately upon definition. This doesn’t work with the Function() constructor.
1 2 3 |
|
Self-Invoking Anonymous Functions
Functions with no identifier that immediately call themselves. These often wrap code to keep it from polluting the global object. Note that it must be wrapped in additional parentheses.
1 2 3 |
|
Hoisting
A function can be invoked before it is defined, because JavaScript collects the functions before runtime. This is called hoisting. It does not work with function expressions.
Recursion
Functions may call themselves while executing. This is called recursion.
Parameters
When creating a function with the constructor, the last param passed in becomes the inside of the function.
1
|
|
You can create a function with too few parameters. The missing ones will be treated as ‘undefined.’
You can also create a function with too many parameters. The extras will be ignored, although they are accessible from the ‘arguments’ property.
Properties and Methods
Properties
- prototype
Instance Properties
- constructor
- length
- arguments
Arguments has a property ‘callee’ that contains a reference to the function currently executing. This can be used in creating recursive functions.
Arguments also has a property ‘length’, containing the number of arguments at invocation. This property is being depricated in favor of arguments.callee.length.
Instance Methods
- apply()
- call()
- toString()
Array()
A special type of object with a couple of extra functions.
Parameters
Any comma-separated parameters passed in will become elements in the array. If a single integer is passed alone, it will define the length of the array instead of an element value. If you define a high index, the elements before it will be filled in with ‘undefined’. Setting an array’s length can add or remove values automatically.
Properties and Methods
Properties
- prototype
Instance Properties
- constructor
- index
- input
- length
Instance Methods
- pop()
- push()
- reverse()
- shift()
- sort()
- splice()
- unshift()
- concat()
- join()
- slice()
String()
Creating Strings
This will create a string object. It is best to avoid this syntax due to potential problems with typeof.
1
|
|
These two create a primitive:
1 2 |
|
Parameters
Takes one parameter: the string value being created.
Properties and Methods
Properties
- prototype
Methods
- fromCharChode()
Instance Properties
- constructor
- length
Instance Methods
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- localeCompare()
- match()
- quote()
- replace()
- search()
- slice()
- split()
- substr()
- substring()
- toLocaleLowerCase()
- toLocaleUpperCase()
- toLowerCase()
- toUpperCase()
- valueOf()
Number()
Creating Numbers
This will create a number object. It is best to avoid this syntax due to potential problems with typeof.
1
|
|
These two create a primitive:
1 2 |
|
Parameters
Takes one parameter: the number value being created.
Properties and Methods
Properties
- MAX_VALUE
- MIN_VALUE
- NaN
- NEGATIVE_INFINITY
- POSITIVE_INFINITY
- prototype
Instance Properties
- constructor
Instance Methods
- toExponential()
- toFixed()
- toLocaleString()
- toPrecision()
- toString()
- valueOf()
Boolean()
Creating Booleans
This will create a boolean object. It is best to avoid this syntax due to potential problems with typeof.
1
|
|
1 2 3 |
|
Parameters
Takes one parameter to be converted into a boolean.
The only false values are: 0, -0, null, false, NaN, undefined, and “”.
Properties and Methods
Properties
- prototype
Instance Properties
- constructor
Instance Methods
- toSource()
- toString()
- valueOf()
Notes
If you create a false boolean object with a constructor, it creates an object. Objects convert to true. Thus do not use the constructor with false booleans.
Primitives: String, Number, and Boolean
A primitive is an irreducible value. The Primitives are: number, string, boolean, null, and undefined.
Primitives are stored in memory with their value:
1 2 3 4 5 6 7 8 |
|
It is best to write these using the literal form. Using a constructor will result in a typeof result of “object” instead of the actual type.
Object Wrappers
When you call a property or method on a primitive, it is wrapped in a temporary object. The temporary object is discarded once the properties have been accessed.
Null
Use null to indicate that an object property doesn’t have a value. It means that a value is expected but not yet available. Calling typeof on it will return ‘object’. It is best to test for null with ===.
Undefined
Used in two ways:
- Indicate that a variable has no assigned value.
- Indicate that an object property you want to access is not defined or named, and can’t be found in the prototype lookup chain.
It is best to let JavaScript itself use undefined. Don’t use it yourself.
Math
This is a built-in, static object. It is not a constructor and cannot be instantiated.
Properties and Methods
Properties
- E
- LN2
- LN10
- LOG2E
- LOG10E
- PI
- SQRT1_2
- SQRT2
Methods
- abs()
- acos()
- asin()
- atan()
- atan2()
- ceil()
- cos()
- exp()
- floor()
- log()
- max()
- min()
- pow()
- random()
- sin()
- sort()
- tan()