Python is a strongly-typed, dynamically typed multi-paradigm language created by Guido Van Rossum.
Javascript is a dynamic, untyped, object-oriented prototypal language created by Brendan Eich.
Swift is a general-purpose, multi-paradigm, compiled programming language developed by Apple.
Functions look like this:
def aFunction(params):
print "Do something"
return 1
All functions return a value.
Code blocks are denoted by indentation. PEP8 specifies that indents should be 4 spaces.
Everything, including functions, are objects in Python.
[aFunction(elem) for elem in aList]
Will return a new list:
“It is safe to assign the result of a list comprehension to the variable that you’re mapping. Python constructs the new list in memory, and when the list comprehension is complete, it assigns the result to the variable.”
.lower( )
.upper( )
.join(aList )
- join any list of strings into a single string. Handy when used in conjunction with list comprehensions.
.split(aDelimiter, timesToSplit)
- splits a string into a list given a delimeter
keys()
- returns list of all keys (in a particular order, but not necessarily order of definition)values()
- returns list of all values: same order as keys()
items()
- returns a list of tuples of the form (key,value)
Nicholas C. Zakas
Notes
Function expressions are not hoisted, so order matters!
The return value of a constructor will be the value returned when called by new
swirl
: R ProgrammingFunctional Requirements
Quality Requirements
Requirements Quality
Completeness
type( )
- returns datatype of an object. Possible types are listed in the types
module.
str( )
- coerces data into a string
Gotchas: string representation of modules includes the pathname of the module on disk.
dir( )
- returns list of attributes and methods of any object
callable( )
- returns True
if object is callable as a function, False
if not. Functions, methods, and classes count as callable.
getattr(object, callablename, defaultvalue)
- returns a reference to a function or method. Works on functions and methods from modules, and on lists and dicts, but not tuples (which have no methods).
A function’s doc strings are accessible as str
types via the __doc__
attribute.
print aFunction.__doc__
The library search path is defined in sys.path
as a list.
You can get the module name with the __name__
attribute. This is commonly used to check if the current script is running as a standalone program:
if __name__ == "__main__"
This is good to use for writing/running test suites for a class or script.
Dynamic.
Dynamically typed.
Functional and object oriented.
Fails silently.
Deployed as source code.
Part of the web platform.
Quirks
No block-scoped variables
No built-in modules
No support for subclassing
No integers (engines optimize this)
Arrays too flexible (engines optimize this)
Elegant Parts
First class functions
Closures
Prototypes
Object literals
Array literals
Influences
Java - syntax
AWK - functions
Scheme - first-class functions and closures
Self - prototypal inheritance
Perl/Python - strings, arrays, regex
HyperTalk - integration into web browsers, event handling attributes in HTML
Netscape originally hired Brandan Eich to implement Scheme in the browser. But then Netscape partnered with Sun to bring Java to the browser. Because of that, JavaScript needed to have syntax similar to Java.
JavaScript’s first name was Mocha. It was renamed to LiveScript before the final name, JavaScript was adopted.
Basic expressions and statements
Comments
Expressions versus statements
Control flow statements and blocks
Rules for using semicolons
Legal identifiers
Invoking methods on number literals
Strict mode
JavaScript’s Type System
Primitive Values Versus Objects
Primitive Values
Objects
undefined and null
Wrapper Objects for Primitives
Type Coercion
Operators and Objects
Assignment Operators
Equality Operators: === Versus ===
Ordering Operators
Plus Operator +
Operators for Booleans and Numbers
Special Operators
Categorizing Values via typeof
and instanceof
Object Operators
Converting to Boolean
Logical Operators
Equality Operators, Ordering Operators
The Function Boolean
JavaScript treats all numbers as 64-bit IEEE-754 numbers. JavaScript engines may optimize for integers internally.
Number Literals
Converting to Number
Special Number Values
The Internal Representation of Numbers
Handling Rounding Errors
Integers in JavaScript
Converting to Integer
Arithmetic Operators
Bitwise Operators
The Function Number
Number Constructor Properties
Number Prototype Methods
Functions for Numbers
String Literals
Escaping in String Literals
Character Access
Converting to String
Comparing Strings
Concatenating Strings
The Function String
String Constructor Method
String Instance Property length
String Prototype Methods
Declaring and Assigning Variables
The Bodies of Loops and Conditionals
Loops
Conditionals
The with Statement
The debugger Statement
What is Exception Handling?
Exception Handling in JavaScript
Error Constructors
Stack Traces
Implementing Your Own Error Constructor
The Three Roles of Functions in JavaScript
Terminology: “Parameter” Versus “Argument”
Defining Functions
Hoisting
The Name of a Function
Which Is Better: A Function Declaration or a Function Expression?
More Control over Function Calls: call(), apply(), and bind()
Handling Missing or Extra Parameters
Named Parameters
Declaring a Variable
Background: Static Versus Dynamic
Background: The Scope of a Variable
Variables Are Function-Scoped
Variable Declarations Are Hoisted
Introducing a New Scope via an IIFE
Global Variables
The Global Object
Environments: Managing Variables
Closures: Functions Stay Connected to Their Birth Scopes
Layer 1: Object-orientation with single objects
Layer 2: Prototype chains of objects
Layer 3: Constructors as factories for instances
Layer 5: Subclassing & Subconstructors
Overview
Creating Arrays
Array Indices
length
Holes in Arrays
Array Constructor Method
Array Prototype Methods
Adding and Removing Elements (Destructive)
Sorting and Reversing Elements (Destructive)
Concatenating, Slicing, Joining (Nondestructive)
Searching for Values (Nondestructive)
Iteration (Nondestructive)
Best Practices: Iterating over Arrays
.js
extension?defer
and async
affect script execution?<head>
part of the document, and what are the drawbacks?defer
attribute in an XHTML tag?<noscript>
element displayed?Objects are instances of a particular reference type. Reference types are also sometimes called object definitions.
Reference types are not classes. JavaScript does not have classes. A new object instance is created with the new
operator.
var butt = new Thing();
ECMAScript provides a bunch of built-in reference classes.
getwd
setwd
list.files
/ dir
args
dir.create
file.create
file.exists
file.info
file.rename
file.copy
file.path
dir.create
unlink
?
:
length
seq
seq(along.with = ... )
seq_along
rep(n, times = ..., each = ...)
NA
NaN
is.na
rnorm
rep
sample
x[is.na(x)]
x[-2]
x[c(-2,-10)]
x[-c(2,10)]
vect <- c(foo = 11, bar = 2, norf = NA)
names(vect)
vect2 <- c(11, 2, NA)
names(vect) <- c("foo", "bar", "norf")
identical(vect, vect2)
vect["bar"]
vect[c("foo", "bar")]
my_vector <- 1:20
dim(my_vector)
length(my_vector)
dim(my_vector) <- c(4,5)
attributes(my_vector)
class(my_vector)
my_matrix2 <- matrix(1:20, nrow = 4, ncol = 5)
patients <- c("Bill", "Gina", "Kelly", "Sean")
cbind(patients, my_matrix)
my_data <- data.frame(patients, my_matrix)
cnames <- c("patient", "age", "weight", "bp", "rating", "test")
colnames(my_data) <- cnames
lapply
and sapply
vapply
and tapply
Constants and Variables
Comments
Semicolons
Integers
Floating-Point Numbers
Type Safety and Type Inference
Numeric Literals
Numeric Type Conversion
Type Aliases
Booleans
Tuples
Optionals
Error Handling
Assertions
Assignment Operator
Arithmetic Operator
Compound Assignment Operators
Comparison Operators
Ternary Conditional Operator
Nil-Coalescing Operator
Range Operators
Logical Operators
String Literals
Initializing an Empty String
String Mutability
Strings Are Value Types
Working with Characters
Concatenating Strings and Characters
String Interpolation
Unicode
Counting Characters
Accessing and Modifying a String
Comparing Strings
Unicode Representations of Strings
Mutability of Collections
Arrays
Sets
Performing Set Operations
Dictionaries
For-In Loops
While Loops
Conditional Statements
Control Transfer Statements
Early Exit
Checking API Availability
Defining and Calling Functions
Function Parameters and Return Values
Function Argument Labels and Parameter Names
Closure Expressions
Trailing Closures
Capturing Values
Closures Are Reference Types
Escaping Closures
Autoclosures
Enumeration Syntax
Matching Enumeration Values with a Switch Statement
Associated Values
Raw Values
Recursive Enumerations
Comparing Classes and Structures
Structures and Enumerations Are Value Types
Classes Are Reference Types
Choosing Between Classes and Structures
Assignment and Copy Behavior for Strings, Arrays, and Dictionaries
Stored Properties
Computed Properties
Property Observers
Global and Local Variables
Type Properties
Instance Methods
Type Methods
Subscript Syntax
Subscript Usage
Subscript Options
Defining a Base Class
Subclassing
Overriding
Preventing Overrides
Setting Initial Values for Stored Properties
Customizing Initialization
Default Initializers
Initializer Delegation for Value Types
Class Inheritance and Initialization
Failable Initializers
Setting a Default Property Value with a Closure or Function
How Deinitialization Works
Deinitializers in Action
How ARC Works
ARC in Action
Strong Reference Cycles Between Class Instances
Resolving Strong Reference Cycles Between Class Instances
Strong Reference Cycles for Closures
Resolving Strong Reference Cycles for Closures
Optional Chaining as an Alternative to Forced Unwrapping
Defining Model Classes for Optional Chaining
Accessing Properties Through Optional Chaining
Calling Methods Through Optional Chaining
Accessing Subscripts Through Optional Chaining
Linking Multiple Levels of Chaining
Chaining on Methods with Optional Return Values
Representing and Throwing Errors
Handing Errors
Specifying Cleanup Actions
Defining a Class Hierarchy for Type Casting
Checking Type
Downcasting
Type Casting for Any and AnyObject
Nested Types in Action
Referring to Nested Types
Extension Syntax
Computed Properties
Initializers
Methods
Subscripts
Nested Types
Protocol Syntax
Property Requirements
Method Requirements
Mutating Method Requirements
Initializer Requirements
Protocols as Types
Delegation
Adding Protocol Conformance with an Extension
Collections of Protocol Types
Protocol Inheritance
Class-Only Protocols
Protocol Composition
Checking for Protocol Conformance
Optional Protocol Requirements
Protocol Extensions
The Problem That Generics Solve
Generic Functions
Type Parameters
Naming Type Parameters
Generic Types
Extending a Generic Type
Type Constraints
Associated Types
Generic Where Clauses
Extensions with a Generic Where Clause
Module and Source Files
Access Levels
Access Control Syntax
Custom Types
Subclassing
Constants, Variables, Properties, and Subscripts
Initializers
Protocols
Extensions
Generics
Type Aliases
Bitwise Operators
Overflow Operators
Precedence and Associativity
Operator Methods
Custom Operators
Switching on strict mode
Caveats on using strict mode
Functions in strict mode
Setting and deleting immutable properties fails with an exception in strict mode
Unqualified identifiers can’t be deleted in strict mode
Features that are forbidden in strict mode
JavaScript’s Types - JavaScript has six types: undefined, null, Boolean, Number, String, and Object.
Static Typing Versus Dynamic Typing/Type Checking - JavaScript is dynamically typed (types not known until runtime). It only does dynamic type checking when trying to use a property of null or undefined.
Coercion - most operands convert operands to a primitive type — Boolean, Number, String, and Object.
booleans, numbers, strings, null, and undefined are primitive types. Everything else in JavaScript is an object. Objects are only strictly equal (===
) to themselves. All primitive types are equal if they contain the same value.
Booleans: true, false
Numbers: IEEE-754 floating point, 64-but
Strings: Unicode characters surrounded by quotes
Undefined: undefined
Null: null
(typeof
returns Object
)
Primitives are compared by value and are immutable. You cannot define new primitive types.
All nonprimitive values are Objects. The most common kinds of objects are plain objects, arrays, and regular expressions.
Objects are compared by reference, mutable by default, and extensible by the user.
undefined
means no value, and uninitialized variables, missing parameters/properties have this value. Functions return undefined
by default.
null
means no object. It is the last element in the prototype chain and gets returns if there is no match for a regular expression.
You can check for them specifically by strict inequality or by implicit conversion to Boolean in a control statement.
Trying to access properties for either leads to an exception (this is the only case).
undefined
can be changed in ECMAScript 3 and earlier. It is read-only in ES5+.
Boolean, Number, and String have wrapper objects. Primitive values borrow methods from these wrapper objects.
Wrapper objects are usually only used implicitly, or for conversion. Creating new wrapper objects with a constructor should especially be avoided.
JavaScript operators force a implicit conversion of operands to an expected primitive type. JavaScript uses an internal function, ToPrimitive()
to do the conversion.
To perform conversion to a different type, use Boolean()
, Number()
, String()
, and Object()
.
All operators in JavaScript coerce operands to expected primitive types. This conversion sometimes causes unexpected behavior for programmers familiar with other languages—notably, arrays cannot be concatenated via operator because they are coerced to strings first. You cannot define or overload the behavior of operators in JavaScript.
===
Versus ==
When testing for equality, always use ===
over ==
.
NaN
is the only value that is never equal to itself.
The void
operator is a unary operator that always evaluates an expression to undefined
. It’s notably used for javascript:
URLs in the browser. It can also be used for IIFEs.
Integer, float, or hexadecimal.
Manually convert with Number(value)
or +value
.
parseFloat(str, radix?)
extracts the first valid floating point numeric string it finds from a string, ignoring whitespace. It parses ''
as NaN
. It is usually better to use Number()
.
NaN
is a number value that is not equal to anything, including itself. It gets produced when number conversions/operations fail. You can check for NaN
with isNaN( )
, but you should also do a type check since isNaN( ) will coerce non-numbers.
Infinity: Infinity
and -Infinity
. Numbers outside the range Number.MAX_VALUE
and Number.MIN_VALUE
, as well as values divided by zero become +/- Infinity. Check for Infinity with strict equality and isFinite( )
.
JS has both positive and negative zero, in accordance with IEEE-754. In most cases, they are indistinguishable. Numbers that approach zero beyond the precision supported become +/- 0
depending on their previous value. Math.pow(x, -1)
, `Math.atan(x, -1), and division by the zero reveal the sign of the zero.
64-bit precision:
Decimal (non-binary) fractions create rounding errors. To compare non-integers, determine equality using an epsilon. The standard machine epsilon is 2^-53
Safe signed integers: (-2^53
, 2^53
) or (Number.MIN_SAFE_INTEGER
, Number.MAX_SAFE_INTEGER
)
Array indices: [0
, 2^32-1
]
UTF-16 codes: 16 bits, unsigned
For a binary operator on integers, you must check both integers and the result to determine if it is safe.
Math.floor()
Math.ceil()
Math.round()
Convert to 32-bit integers via bitwise |0
and shift operators.
parseInt(str, radix?)
gets
Single quoted and double quoted strings are equivalent.
Line continuations - backslash and plus operator
Character escape sequences
NUL character
Hexadecimal escape sequences for characters
Unicode escape sequences
String.charAt(i)
String( )
''+value
value.toString()
JSON.stringify(value, replacer?, space?)
comparison operatorsString.prototype.localeCompare( )
+
Adding to array then joining
String( v )
String.fromCharCode( c1, c2, ... )
String.prototype.charCodeAt( i )
length
Number of characters in string. Immutable. Characters represented by escape codes are counted as one character.
Extract Substrings
Transform
Search and Compare
Test, Match, and Replace with Regular Expressions
var
declares a variable. Variable declarations are hoisted. =
assigns. They can be combined.
Loop body is a single statement or a code block.
[label]:
break
continue
while
do-while
for
for-in (use Array.prototype.forEach( )
for Arrays)
for-each-in (Firefox only)
if-then-else
switch
Depreciated!
debugger;
throw
try-catch-finally
At least throw a new Error( ... )
instead of a string. Environments may provide a stack trace with the error object.
Error
EvalError
- not usedRangeError
ReferenceError
SyntaxError
TypeError
URIError
Propertiesmessage
name
stack
You can set the message
property of the error. Engines may support the stack
property.
Nonmethod function (“normal function”)
Constructor
Method
parameters - (formal parameters/arguments) used in the function definition
arguments - (actual parameters/arguments) in the function invocation
Function Expressions - anonymous or named
Function Declarations - hoisted
The Function Constructor - Similar to eval
. Don’t use this in general.
Only function declarations are completely hoisted. var
is hoisted, but assigning a function expression is not.
Most JS engines support the property name
, which is useful for debugging.
func.apply(thisValue, argArray)
func.bind(thisValue, arg1, ..., argN)
More actual parameters than formal parameters - extra parameters ignored but are still in arguments
Fewer actual parameters than formal parameters - missing parameters get undefined
arguments
- array-like object—has length
and can access elements with []
but no other array methods.
Strict vs Sloppy mode: callee
property is depreciated and is not allowed in strict mode. In sloppy mode, arguments change when parameters change, but not in strict mode. Strict mode prevents assigning to arguments
.
Mandatory Parameters, Enforcing a Minimum Arity
Optional Parameters
Simulating Pass-by-Reference Parameters - enclose in an array.
Pitfall: Unexpected Optional Parameters
JavaScript doesn’t support named parameters directly. Simulate by passing in an object.
Statically (or lexically)
Dynamically
The scope of a variable
Lexical scoping
Nested scopes
Shadowing
It is immediately invoked
It must be an expression
The trailing semicolon is required
IIFE Variation: Prefix Operators
IIFE Variation: Already Inside Expression Context
IIFE Variation: An IIFE with Parameters
IIFE Applications
PITFALL: ASSIGNING TO AN UNDECLARED VARIABLE MAKES IT GLOBAL
Brandon Eich considers the global object one of his biggest regrets.
Browsers - window
- standardized as part of the DOM, not ES5
Node.js - global
Use Cases for window
Dynamic dimension: invoking functions - stack of execution contexts
Lexical (static) dimension: staying connected to your surrounding scopes - chain of environments
Handling Closures via Environments
Kinds of Properties
Object Literals
Dot Operator
Unusual Property Keys
Bracket Operator
Converting Any Value to an Object
call( ), apply( ), bind( )
apply( ) for constructors
pitfall: losing this
when extracting a method
pitfall: functions inside methods shadow this
Inheritance. Overriding. Sharing data between objects via a prototype. Getting and setting the prototype. __proto__
. Setting and deleting affects only own properties.
Iteration and Detection of Properties. Listing own property keys. Listing all property keys. Checking whether a property exists.
Best Practices: Iterating over Own Properties.
Accessors (Getters and Setters). Defining accessors via an object literal. Defining accessors via property
descriptors. Accessors and inheritance.
Property Attributes and Property Descriptors. Property Attributes. Property Descriptors. Getting and Defining Properties via descriptors. Copying an object. Properties: definition versus assignment. Inherited read-only properties can’t be assigned to. Enumerability: best practices.
Protecting Objects. Preventing extensions. Sealing. Freezing. Pitfall: protection is shallow.
What is a constructor in JavaScript? The new operator implemented in JavaScript. Terminology: the two prototypes. The constructor property of instances. The instanceof
operator. Tips for implementing constructors.
Data in Prototype Properties. Avoid prototype properties with initial values for instance properties. Avoid nonpolymorphic prototype properties. Polymorphic prototype properties.
Keeping Data Private. Private data in the environment of a constructor (Crockford Privacy Pattern). Private data in properties with marked keys. Private data in properties with reified keys. Keeping global data private via IIFEs.
Inheriting Instance Properties
Inheriting Prototype Properties
Ensuring That instanceof
Works
Overriding a Method
Making a Supercall
Avoiding Hardcoding the Name of the Superconstructor
Example: Constructor Inheritance in Use
Example: The Inheritance Hierarchy of Built-in Constructors
Antipattern: The Prototype Is an Instance of the Superconstructor
Conversion to Primitive
Object.prototype.toLocaleString()
Prototypal Inheritance and Properties
Accessing Object.prototype and Array.prototype via Literals
Examples of Calling Methods Generically
Array-Like Objects and Generic Methods
A List of All Generic Methods
Pitfall 1: Inheritance Affects Reading Properties
Pitfall 2: Overriding Affects Invoking Methods
Pitfall 3: The Special Property __proto__
The dict Pattern: Objects Without Prototypes Are Better Maps
Best Practices
Array syntax
Arrays Are Maps, Not Tuples
Arrays Can Also Have Properties
Array Literals/The Array Constructor
Multidimensional Arrays
indices i go from 0 ≤ i < 2^32−1
max length
is 2^32-1
Indices out of range are treated as string property keys.
The in Operator and Indices
Deleting Array Elements
Array Indices in Detail
length
only keeps track of the highest index. It doesn’t count nonholes.
Trying to construct an array with length > 2^32-1 will cause a RangeError: Invalid array length
.
Manually Increasing the Length of an Array
Decreasing the Length of an Array
Creating Holes
Sparse Arrays Versus Dense Arrays
Which Operations Ignore Holes, and Which Consider Them?
Removing Holes from Arrays
Use Array.isArray(obj)
instead of instanceof
to detect Arrays.
Array.prototype.shift()
Array.prototype.unshift(elem1?, elem2?, ...)
Array.prototype.pop()
Array.prototype.push(elem1?, elem2?, ...)
Array.prototype.push.apply(thisValue, argArray)
Array.prototype.splice(start, deleteCount?, elem1?, elem2?, ...)
``
Array.prototype.reverse()
Array.prototype.sort(compareFunction?)
Comparison functions should return the following:
Result | Return Value |
---|---|
less than | -1 |
equal | 0 |
greater than | 1 |
Comparing Numbers
Use conditional statements. Subtracting can cause overflow.
Comparing Strings
Use String.prototype.localeCompare
Array.prototype.concat(arr1?, arr2?, ...)
Array.prototype.slice(begin?, end?)
Will copy the array if no indices are provided.
Array.prototype.join(separator?)
Uses ,
as a default separator.
Array.prototype.indexOf(searchValue, startIndex?)
Returns index of first match, or -1
if not found. Uses strict equality.
Array.prototype.lastIndexOf(searchElement, startIndex?)
Searches from startIndex
to the beginning of the array.
Examination - forEach( )
every( )
, some( )
Transformation - map( )
filter( )
Reduction - reduce( )
reduceRight( )
for
loopforEach()
, some()
, every()
, map()
, filter()
, reduce()
, reduceRight()
)Don’t use for-in
, since that will iterate over all properties, not elements.
Data Type | typeof( ) |
Description |
---|---|---|
Undefined | 'undefined' |
undefined ; uninitialized/undeclared variables |
Null | 'object' |
null |
Boolean | 'boolean' |
true false |
Number | 'number' |
integers, floating point, +/-Infinity , NaN |
String | 'string' |
characters, character literals, empty strings |
Object | 'object' |
JavaScript objects |
+
-
++
--
~
&
|
^
<<
>>
>>>
!
&&
||
*
/
%
+
-
<
>
<=
>=
==
!=
===
!===
=
*=
/=
+=
-=
%=
<<=
>>=
>>>=
,
undefined
undefined
arguments
object: acts like an array, but is not instance of Arrayvar beets = function(){
if (arguments) {
if (arguments.length >= 3) {
for (x in arguments) {
console.log(x);
}
} else if (arguments.length === 2) {
console.log('1. ' + arguments[0]);
console.log('2. ' + arguments[1]);
} else {
console.log('only argument: ' + arguments[0]);
}
}
}
Arguments stay in sync with named parameters:
Primitive values are accessed by value.
Objects are accessed by reference.
You can add properties to reference values at any time.
Trying to add properties to primitive values won’t work, but also won’t cause an error.
Assigning a primitive value creates a new copy.
Assigning a reference value passes the reference to the same object instance.
Always passed by value—value is copied into a local variable. Passing by reference is not possible in JS. This functionality is replaced by closures.
typeof( )
returns the type of primitive values.
variable instanceof
Constructor returns true
if X is an instance of reference type with constructor Constructor.
Execution Context - defines access and behavior for a variable or function—what other data it can access. This is not accessible directly by code.
An inner context can access variables in an outer context, but not the other way around.
In web browsers, the global execution context is the window
object. Each function has its own local execution context.
The other primary type of context is the function execution context.
Scope Chain provides access to all variables and functions in the execution context.
The Variable Object is the front of the Scope Chain.
In Functions the Activation Object is used as the variable object.
Each context can search up the scope chain, but not down.
catch
and with
null
helps minimize memory usageTwo ways to create an Object instance explicitly
Object literal notation, and when it is used
Expression context, statement context, how context affects interpretation of {
Property names in object literal notation
Creating an empty object
Way to access object properties
When bracket notation is favored
Arrays can hold any data type at any index. (They are more similar to lists in Python than Arrays in Java.)
There are two main ways to create arrays: the Array constructor and an Array literal.
Array elements are accessed via index and square bracket.
ben[1] = "helicopter";
The number of elements in an array is given by the length
property.
The length property is mutable: decreasing length
truncates elements from the end of the Array. Increasing length
appends elements with the value of undefined
to the end of the array.
colors[colors.length] = "butt brown"; // appends value to end of array
ECMAScript Date
represents dates as the number of milliseconds since midnight 1970-01-01 UTC.
Create a new Date object with the new
operator and the Date()
constructor.
Without arguments, the object is set to the current date and time.
var now = new Date();
Reference type methods
Date.parse( dateString )
Parses strings containing a date, returning the UTC date in milliseconds. The Date( )
constructor calls parse( )
if passed a string. Supports several formats as defined by ECMA-262 Fifth Ed.:
mm/dd/yyyy
Month_name dd, yyyy
Day_of_week Month_name dd yyyy hh:mm:ss Time_zone
yyyy-mm-ddThh:mm:ss.sssZ
(ECMAScript 5 compliant implementations only)Returns NaN
if the string can’t be parsed as a date (this happens when the date string doesn’t exactly match one of the supported patterns.)
Date.UTC( y, m[, d, h, m, s, ms] )
Returns the local timezone’s date in milliseconds for a specified UTC year, month, day, hour, minute, seconds, and milliseconds.
Regular Expression literal:
var exp = /{pattern}/{flags}
Supported flags:
g
: globali
: case insensitivem
: multilineRegEx Metacharacters
( [ { \ ^ $ | ) ] } ? * + .
Metacharacters need to be escaped with \
if they are part of the pattern.
RegEx Constructor
var expression = /\$\( +\)\./gm;
var equivExpression = new RegEx("\\$\\( +\\)\\.","gm");
Note how metacharacters need to be double-escaped in the string.
Differences between literal and constructor creation patterns
In ECMAScript versions before 5, regular expression created as a literal will always reference the same RegExp instance (the instance properties remain in the same state.)
A regular expression created with a constructor will always create a new RegEx instance.
In ECMAScript 5, the literal pattern creates a new instance, like the RegEx constructor.
input $_
lastMatch $&
lastParen $+
leftContext $`
multiline $*
rightContext $'
There are three main ways to define a function:
function f(args, bargs, dargs) {
}
var f = function(args, bargs, dargs){
};
Note the need of a semicolon, since this is an expression and not a code block.
var f = new Function('args', bargs', 'return args+bargs");
Don’t use this. It causes double interpretation of code.
Function names are pointers to function objects.
This is why there is no overloading—declaring two functions with the same name just overwrites the earlier one with the later one.
Allows primitive values to be treated as objects with methods.
When a boolean, number, or string primitive value is accessed in read mode and a method is called, the following steps occur:
Automatically created primitive wrapper types are destroyed immediately after use. This means that you cannot add properties or new methods to primitive types.
Primitive wrappers can be explicitly created with constructors, but this should only be done in rare need. Any values created with the new
operator and constructor will return typeof “object”.
The Object constructor can return an instance of a primitive wrapper by passing in the primitive.
var obj = new Object("a blah");
console.log(obj instanceof String); // true
eval()
Math
let
var
Declaring Constants and Variables
All constants need to be initialized. All variables also need to be either initialized or type annotated.
let chessBoardMaxRank = 8 // constant
var currentRank = 1 // variable
Type Annotations
var lastName: String
var heightM: Double
var year: Int
var elements: Array
You can declare and annotate variables of the same type on a single line, separated by commas.
Naming Constants and Variables
Printing Constants and Variables
Single-line comment: //
Multi-line comment: /* */
Multi-line comments can be nested.
Semicolons are only required to separate two or more statements on a single line.
Integer Bounds
Int
UInt
Double
: 64-bit floating-point numberFloat
: 32-bit floating-point number
Swift is a type-safe language and performs type checks during compilation.
Swift uses type inference to determine the types of not-explicitly declared variables and constants.
0b
prefix0o
prefix0x
prefixFloating-point literals can be either decimal or hexadecimal. Decimal floating points can have an optional exponent, indicated with e
or E
. Hexadecimal floating point numbers need an exponent, indicated with p
or P
.
Integer Conversion
Use the Int
type for general purpose integer constants and variables.
Integer and Floating-Point Conversion
typealias
Bool
Booleans can be one of two constant values: true
or false
.
Attempting to substitute non-Boolean values for Bool will cause an error.
( value, ...)
Group multiple values into a compound value. The values can be of any (and mixed) types.
Decompose a tuple’s contents by assigning to a tuple. Underscore ignores contents.
let (realNum, imagNum) = z
let (_, imaginaryPortion) = z
You can access a tuple’s elements using index numbers (starting at 0
) or element names.
print(“Latitude is (coord.y)”)
print(“Longitude is (coord.x)”)
let altitude = coord.2
Tuples can be return values of functions with multiple return values[1].
Use when a value may be absent: an optional either has no value, or wraps the actual variable.
nil
Set an optional to nil
to give it no value. If an optional is defined but not initialized, it is automatically set to nil
.
Note: nil
is not a pointer to a null object. Even non-object optionals can be set to nil
.
If Statements and Forced Unwrapping
!
unwraps an optional’s value. But it will cause a runtime error if the optional is nil
.
Optional Binding
Check if an optional has a value before entering a code block (if
or while
).
if let number = Int(input) {
return(number^2)
}
Separate a series of optional bindings (and booleans) with commas — if any is nil
, the statement will evaluate to false.
Implicitly Unwrapped Optionals
Unwrap the optional automatically.
throws
do
try
catch
Swift propagates errors out of the current score until a catch
clause handles it.
Debugging with Assertions
When to Use Assertions
input
is primitive, return itinput
is a number or string:input.valueOf()
and return if primitiveinput.toString()
and return if primitiveinput.valueOf()
or input.toString()
and return if primitiveTypeError
Falsy values - converted to false
:
undefined
, null
false
0
,NaN
''
(empty/zero-length string)All other values are converted to true.
Inheritance
Overriding
Sharing data between objects via a prototype
Getting and setting the prototype__proto__
Setting and deleting affects only own properties
Listing own property keys
Listing all property keys
Checking whether a property exists
Defining Accessors via an Object Literal
Defining Accessors via Property Descriptors
Accessors and Inheritance
Property Attributes
Property Descriptors
Getting and Defining Properties via Descriptors
Copying an Object
Properties: Definition Versus Assignment
Inherited Read-Only Properties Can’t Be Assigned To
Enumerability: Best Practices
Preventing Extensions
Sealing
Freezing
Pitfall: Protection Is Shallow
Constructor overview
.prototype
.constructor
instanceof
The instanceof operator
value instanceof Constr
Constr.prototype.isPrototypeOf(value)
Tips for implementing constructors:
new
Why you usually shouldn’t put data in prototype properties.
Why avoid prototype properties with initial values for instance properties: mutating the value on the instance before it’s overwritten with an own property will change the prototype default value!
Avoid nonpolymorphic prototype properties, like constants. Use variables instead.
Polymorphic prototype properties can be used for tagging instances across realms.
JavaScript doesn’t have a built-in means for data privacy. There are three main patterns for using data privacy:
Private data in the environment of a constructor (Crockford privacy pattern) - functions created as part of a constructor are part of that constructor’s closure. They can act as privileged methods that access data that is part of the constructor’s environment. Not very elegant, may be slower, consumes more memory, but it’s completely secure.
Private data in properties with marked keys (private by convention) - usually with a naming convention like an underscore. This offers a more natural coding style, but it pollutes the property namespace because they’ll show up as normal properties. It can also lead to key clashes. They can be accessed normally, which can be flexible for unit tests and stuff.
Private data in properties with reified keys - storing the key value in a variable. This avoids key clashes and lets you use UUIDs that can have unique values at runtime.
You can keep global data private via IIFEs: attaching it to a singleton object, keeping it private to a constructor, attaching it to a method
For two constructors Super
and Sub
we want:
instanceof
to work for instancesObject.prototype
methodsConversion to Primitive
Object.prototype.toString()
Object.prototype.valueOf()
Object.prototype.toLocaleString()
Prototypal Inheritance and Properties
Object.prototype.isPrototypeOf(obj)
Object.prototype.hasOwnProperty(key)
Object.prototype.propertyIsEnumerable(propKey)
Pitfall 1: Inheritance Affects Reading Properties
Pitfall 2: Overriding Affects Invoking Methods
Pitfall 3: The Special Property proto
Creating an object without a prototype (Object.create(null)
) avoids all of these pitfalls.
var arr = ['a', 'b', 'c'];
arr.length;
arr.length = 2;
arr[arr.length] = 'd';
arr.push('e');
var e = arr.pop();
The Array
type is an object with properties that have integer indices as names.
The elements of an Array are not necessarily contiguous, and Arrays can have “holes”, or missing indices.
Arrays work like any other object. You can add arbitrary properties to them. These new properties are not considered array elements by array methods.
// Array literal
var arr = ['a', 'b', 'c']
Array Constructor
Why the Array( )
constructor is problematic:
Creating an empty array with a given length
// creates an array object with length 2
var arr = new Array(2);
// elements at indices are still undefined
Initializing an array with elements via constructorArray( )
will try to parse a numeric argument as a length
// Array with two holes, not [2]
var arr = new Array(2);
// RangeError: Invalid array length
arr = new Array(9.9);
Create multidimensional arrays by nesting arrays. Make sure to create the rows (outer arrays). You have to do this with a loop (since a constructor will just set the length
of the outer array)
delete
works on array elements but doesn’t update length
or shift elements. It creates a hole.
To delete elements without leaving a hole, use Array.prototype.splice()
// remove i
arr.splice(i, 1);
// remove j through k
arr.splice(j,k-j+1);
// remove m up to but not including n
arr.splice(m, n-m);
// remove the third last element and after
arr.splice(-3);
Indices aren’t numbers, but string property keys.
For a key P that is a valid array index:
ToString(ToUint32(P)) === P
is trueToUint32(P) !== Math.pow(2,32)-1
Changing length only creates holes (doesn’t create new, empty array elements).
This does actually delete elements (trying to access afterwards will return undefined
)
You can clear an array by setting length
to 0
. This clears the array for all variables accessing the object. But this operation can be slow and it is easier to create a new, empty array.
You can create holes by omitting values in literals and assigning to nonconsecutive indices.
Trying to access a hole returns undefined
. Unlike an actual undefined
at that index, it’s not detected by the in
operator. Array iteration methods also ignore them.
Array iteration methods
Method | Behavior |
---|---|
forEach() |
ignores |
every() |
ignores |
map() |
skips but preserves |
filter() |
eliminates |
Method | Behavior |
---|---|
join() |
converts holes, undefined , null to '' |
sort() |
preserves while sorting |
Function.prototype.apply()
When apply()
accepts an otherwise empty array with holes, it turns them to undefined
.
You can create an array with undefined as values with Array.apply
. But apply
wont’ necessarily replace holes with undefined
in nonempty arrays.
filter( )
removes holes.
To replace holes with undefined
, use a loop that assigns each array element to itself.
Examination Methods
Array.prototype.forEach(callback, thisValue?)
- iterates over all elements. Doesn’t support break—use some( )
instead
Array.prototype.every(callback, thisValue?)
- true
if true for every element; stops as soon as it gets false
Array.prototype.some(callback, thisValue?)
- returns true
if the callback returns true
for at least one element. Stops iteration once it gets a true
Transformation Methods
function callback(element, index, array)
Array.prototype.map(callback, thisValue?)
- return an array with callback applied to each element
Array.prototype.filter(callback, thisValue?)
- return a new array containing only elements for which callback returned true
Reduction Methods
function callback(previousValue,
currentElement, currentIndex, array)
Array.prototype.reduce(callback, initialValue?)
Array.prototype.reduceRight(callback, initialValue?)
If initial value is not provided, previousValue
is the first element and currentElement
is the second element.
null
undefined
Integers (dec, octal, hex)
55
070
0xA
Floating Point (IEEE 754)
301.001
2.91E23
Range: Number.MIN_VALUE
Number.MAX_VALUE
Infinity
-Infinity
- can’t be used in further calculations. Check with isFinite( )
.
NaN
- detect with isNaN( )
Cast to number type with Number( )
Characters, character strings, character literals.
''
or double ""
quotes.\n\t\\
, unicode, etc) are counted as single characters, not by the number of characters in their ascii escape sequence.toString( )
_JavaScript objects
All objects have the following methods:
hasOwnProperty( prop )
isPrototypeOf( obj )
propertyISEnumerable( prop )
toLocaleString()
- return string representation of object that is appropriate for localetoString()
- string representation of objectvalueOf()
- string, number, or Boolean representation of object+
-
+
does nothing to a number type variable, casts the variable using Number()
-
negates a number type variable, and returns the negation of a non-numeric value after its converstion with Number()
!
&&
||
Operand | ! |
---|---|
true |
false |
false |
true |
object | false |
empty string | true |
nonempty string | false |
0 |
true |
nonzero number | false |
null |
true |
NaN |
true |
`undefined | true |
&&
will always short circuit to false
if the first operand is false
.
||
will always short circuit to true
if the first argument is true
Operand1 | Operand2 | && |
OR |
---|---|---|---|
true |
true |
true |
true |
true |
false |
false |
true |
false |
* | short circuit false |
Operand2 |
true |
false |
false |
short circuit true |
Object | * | Operand2 | Operand1 |
true |
Object | Operand2 | short circuit true |
Object | Object | Operand2 | Operand1 |
null |
* | null |
null if Operand2===null |
NaN |
* | NaN |
NaN if Operand2===NaN |
undefined |
* | undefined |
undefined if Operand2===undefined |
undeclared | * | error | error |
true |
undeclared | error | short circuit true |
false |
undeclared | short circuit false |
error |
Allows execution of more than one operation in a single statement.
Usually used for variable declaration.
var a1=1,
a2=2,
a3=3;
When used to assign values, returns the last item in the expression.
var num = (5, 1, 4, 8, 0); // num = 0
butts: for (var i=0; i < count; i++) {
console.log(i*i);
}
break
exits a loop immediately, and the next statement after the loop is executed.
continue
exits a loop iteration, but execution resumes the beginning of the loop.
You can specify a labeled statement as the target of break
or continue
. This is powerful but can cause debugging problems.
Not allowed in strict mode. Don’t use in production code.
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
is equivalent to:
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
Matches similar to ==
. Works with all data types, including strings and objects. Case values do not need to be constants.
Starts with arguments
.
Next variable object is from the containing context.
Each subsequent variable object in the chain is that of the next immediately enclosing scope.
The last variable object in the chain belongs to the global scope.
A catch
block in a *try-catch statement and a with
statement both add a variable object to the front of a scope chain.
with
with (aThing) {
/* ... */
}
aThing
is added to the scope chain.
try-catch
try {
} catch (e) {
/* ... */
}
The catch
statement will create a new variable object containing e
, the error object that was thrown.
Variables declared in blocks, such as in if
statements and in the initialization part of for
statements are available in the rest of the enclosing function scope.
Declaring a variable with var
will add it to the immediate context.
!
- A variable that gets initialized without being declared gets added to the global context: it will continue to exist until execution exits the global scope.
Always declare variables before initializing this to avoid problems.
Identifiers get resolved by navigating the scope chain from beginning to end.
A variable is accessible as long as it can be found in the scope chain.
The search may also search each object’s prototype chain.
The first match in the identifier search gets returned.
var name = "Khyr ad-Din";
function getName() {
var name = "Edmund Harvey";
return name;
}
console.log(getName()); // "Edmund Harvey"
In this case the name variable in the parent context of getName can’t be accessed.
Cyclic References Example
function thing() {
var objA = new Object();
var objB = new Object();
objA.friend = objB;
objB.friend = objA;
}
Even once browsers switched to mark-and-sweep GC, non-native JavaScript objects (COM, DOM, BOM) in IE8 and earlier were still vulnerable to cyclic references because they were still implemented with reference counting.
!
- Make sure to break the connection between native JS and DOM elements by setting cross-references to null
.
IE6 and earlier ran GC when threshold of 256 variable allocations, 4096 object/array literals/array slots, or 64kb of strings was reached.
Scripts with a lot of variables/strings kept the GC running really frequency, leading to performance issues.
IE7 instead had dynamic thresholds based on how many allocations were reclaimed per sweep.
There are two main ways to create an array:
var anEmptyArray = []; // creates an empty array
var numbersAgain = [1,2,]; // don't do this
var numbersOrWhat = [,,,,,] // don't do this either
Creating empty arrays with commas, or leaving the last element blank causes inconsistent behavior. In IE8 and earlier, the last, hanging comma will create an additional index with the value undefined
(this is a bug). Other browsers will not create an additional index giving a hanging comma.
Array literal notation doesn’t call the Array()
constructor except in Firefox 2.x and earlier.
x instanceof Array
will not correctly identify x
as an Array if it was passed from a different frame or page, and x
‘s array type has a different constructor.
Instead, ECMAScript 5 provides Array.isArray( anObject )
to detect arrays.
.toString()
.valueOf()
Returns a comma delimited list of each element’s .toString()
values.
.toLocaleString()
Returns a comma delimited list of each element’s .toLocaleString()
values.
.join(sep)
Returns a list separated by the string specified by sep
.
If sep
is not provided or undefined, it uses a comma. IE 7 and before has a bug that uses undefined
as the delimiter.
push(itemTachi, ...)
Appends any number of elements to the end of an array.
pop()
Returns the last element of the array and decrements the length
property.
shift()
Returns the first element of the array removes it from the array (shifting all the indicies downward).
unshift(elemTachi, ...)
Prepends any number of elements to an array.
.reverse()
- reverses the elements in the array.
.sort( comparator )
Sorts the elements of the array based on a comparison function. For each pair of elements in an array, the comparison function should basically do this:
function comparator(v1, v2) {
if ( /* v1 < v2 */) {
return -1;
} else if (/* v1 > v2 */) {
return 1;
} else {
return 0;
}
}
If no comparison function is provided, sort()
will return the elements in sorted in ascending order of their String()
values by default.
.concat( elementsOrArraysTachi, ... )
Returns a new array with specified elements appended to the end of the original array. Will append the elements of any arrays passed into it. If no elements or arrays are passed in, it will clone the original array.
.slice( startIndex, stopIndex )
Returns a new array containing elements between startIndex
and up to but not including stopIndex
. stopIndex
is optional and if it is not specified, slice( )
will just return elements from startIndex up to the end of the array.
.splice(startIndex, replaceCount, elem[,...] )
Splice can delete, insert, or replace items in the middle (or at any point) of an array.
Deletion - specify two arguments: startIndex
is the first item to delete, and replaceCount
is the number elements to delete.
Insertion - specify three or more arguments: startIndex
is the insertion point, have replaceCount=0, and then specify any number of elements to insert.
Replacement - specify three or more arguments: startIndex
is the replacement point, replaceCount
is the number of elements to delete, and elem[…] are the items to insert.
Each of these uses the ===
operator to find a match:
.indexOf()
.lastIndexOf()
Let f( )
be a function that takes the following arguments (all optional):
function f(elem, i, array)
Each of the following methods run f( )
for each element in the array. The current element is passed as elem
, the index as i
, and the array itself as array
.
Method | return value |
---|---|
.every(f) |
true if f( ) returns true for every element in the array, false otherwise |
.filter(f) |
array of all items for which f( ) returns true |
.forEach(f) |
no return value |
.map(f) |
result of each call to f( ) , as an array |
.some(f) |
true if f( ) returns true for any item |
.reduce(f, iv)
.reduceRight(f, iv)
Iterates through all elements of an array, either from the first element (reduce
) or from the last element reduceRight
.
function f(prev, cur, index, theArray) {
/* ... */
return val;
}
iv
(optional) is passed in as prev on the first iteration (when cur is set to element 0).
The return value of the function (val
in f) is passed in as prev
on the next iteration.
e.g. sequences, series, iterative algorithms
Function Declarations are available in an execution context before any code is executed. This is called function declaration hoisting. The engine takes any Javascript function it finds and brings it to the top of the source tree.
Function Expressions aren’t available until the line of code (usually assigning a function to a variable) gets executed. If a function gets called before it’s assigned in a function expression, it will cause an “unidentified identifier” error.
Functions can be used any place any other value can be used.
It’s possible to:
This is important—you can use this to create a comparison function to use with sort()
that knows what properties of objects to compare.
A function contains three special objects:
arguments
- Contains arguments passed to the function and a property callee
which is a pointer to the function that owns the arguments object. This can be important for decoupling arguments from the function’s label, such as in recursive functions.
arguments.callee
results in an error.arguments.caller
. Accessing arguments.caller
in strict mode causes an error. Example: write a recursive function (recursive merge sort, factorial) that still works even the name of the function gets changed.
this
- a reference to the context object the function is operating on. The value of this
is not determined until the function is called. It is set to the global context by default.
this
is set to undefined unless apply()
or call()
are used.Example: write a function that uses this
to produce different output depending on the object that is the context (e.g. window vs. an object).
caller
- (ECMAScript 5) contains a reference to the calling function, or null
if the function was called in the global scope.
caller
causes an error.Properties
length
- the number of named arguments that the function expects
prototype
- prototype for reference types. Not enumerable in ECMAScript 5.
Methods
apply(valueOfThis, argsArray)
call(valueOfThis, arg1[,...] )
Execute the function with a particular this
context. apply
accepts an array of arguments (either an Array type or the arguments
object) and call
accepts any number of arguments directly.
window.color = "red";
var o = { color: "blue" };
function sayColor() {
console.log(this.color);
}
sayColor(); // red
sayColor.call(this); // red
sayColor.call(window); // red
sayColor.call(o); // blue
bind(thisValue)
(ECMAScript 5)
Creates a new function object instance with the this
value set to the specified value.
window.color = "Aquamarine";
var o = { color: "CornflowerBlue" };
function sayColor() {
console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); // CornflowerBlue
toString()
toLocaleString()
Returns the function’s code.
valueOf()
- Returns true
or false
toString()
toLocaleString()
- Returns 'true'
or 'false'
(string values)
Don’t use Boolean types in boolean expressions! They are treated and evaluated as objects.
valueOf()
- Returns the primitive numeric value.
toString()
toLocaleString()
- Return the string representation of the numeric value.
toFixed(places)
- string representation of a number with a specified number of decimal points, rounded.
Rounding is bugged in IE 8 and earlier: it rounds numbers in (-0.94,-0.5]
[0.5,0.94)
when precision is 0
. It will round numbers in these ranges to 0
when they should be rounded to 1
or -1
.
toExponential(places)
- string representation in e-notation.
var num = 10;
console.log(num.toExponential(1)); // '1.0e+1'
toPrecision(precision)
- returns string representation of number in either fixed or exponential notation with precision
number of digits, rounding when appropriate. Can typically represent numbers with 1 through 21 decimal places.
String Character Methods
charAt(i)
- returns character at position in string
charCodeAt(i)
- returns character code at position in string
ECMAScript 5 allows bracket notation.
var s = “My Butt”;
console.log(s[3]); // ‘B’
String-Manipulation Methods
concat( )
- return concatenation of one or more strings
slice(startPos, stopPos)
length
+arg.substring(startPos, stopPos)
0
.substr(startPos, count)
length
+arg.0
.String Location Methods
indexOf(s)
lastIndexOf(s)
The trim()
Method
trim()
- Returns a copy of a string with leading and trailing white space removed.
trimLeft()
trimRight()
- Nonstandard methods supported in Firefox 3.5+, Safari 5+, Chrome 8+.
String Case MethodstoLowerCase()
toLocaleLowerCase()
toUpperCase()
toLocaleUpperCase()
String Pattern Matching Methodsmatch( regEx )
- returns an array where the first element is the string that matches the entire pattern, and then capturing groups
search( regEx )
- returns index of substring matching regular expression or -1
if not found
replace( searchText, r )
- matches based on a regular expression or a string. r
can be string or a function. If r
is a string, it supports special codes for replacement text. If r
is a function, it gets passed three arguments: the string match, the position of the match, and the whole string. Additional capturing groups can get passed in as an argument. The only way to replace all occurrences is to pass in a RegEx type with the g
flag set.
r
is a string, you can insert regular expression operation values. (See table).split(sep, arrayLimit)
- separates a string into an array of substrings based on separator sep
, which may be a string or RegEx
localeCompare(s)
- comparator method that returns different values based on whether a string comes before another alphabetically (return values vary slightly by implementation)
-1
)0
1
)String.fromCharCode( num[,...], )
- creates a string from character codes
Propertiesundefined
NaN
Infinity
Object
Array
Function
Boolean
String
Number
Date
RegExp
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
Window Object
In browsers, the window
object acts as the global object’t delegate, and it gets all the variables and functions declared in the global scope.
encodeURI(s)
- encodes a string into a valid URI. Meant to be used on an entire URI, so does not encode valid URI components, such as colons, forward slashes, question marks, and percent signs.
encodeURIComponent(s)
- encodes all nonstandard characters
decodeURI(s)
- decodes the characters of a URI into a string. Only decodes characters that would have been replaced by encodeURI()
decodeURIComponents(s)
- decodes a URI into a string
eval()
methodMath
ObjectProperties (constants)
Math.E
MathLN10
Math.LN2
Math.LOG2E
- base 2 log of eMath.LOG10E
- base 10 log of eMath.PI
Math.SQRT1_2
- square root of 1/2Math.SQRT2
Methods
Math.min(x1[, ...] )
- returns the smallest number in a group of numbers. Accepts any number of parameters.
Math.max(x1[, ...] )
- returns the largest number in a group of numbers.
Math.ceil(x)
- ceiling function
Math.floor(x)
- floor function
Math.round(x)
- rounds number up if decimal component is >= 0.5, or down if not.
Math.random()
- generates a random number in (0,1)
Other methods:
Math.abs(x)
Math.exp(x)
- e^xMath.log(x)
Math.pow(x, t) - x^t
Math.sqrt(x)`Math.acos(x)
- arc cosine of xMath.asin(x)
- arc sine of xMath.atan(x)
- arc tan of xMath.atan2(y,x)
- arc tangent of y/xMath.cos(x)
- cosine xMath.sin(x)
- sine xMath.tan(x)
- tan x
The precision of results may vary from implementation to implementation.
Data properties and Accessor properties are the two types of properties in JavaScript.
Data Properties - single location for a data value
Accessor Properties - combination of getter/setter functions
What the new
operator actually does
constructor
property of instances
Use cases for the constructor property:
.constructor.name
. (Not all JS engines support function property name
.)Best practice: make sure that for a constructor C
, C.prototype.constructor === C
is true
. Functions have this set up correctly by default. Avoid replacing the prototype
object, and if you do, manually assign the right value to constructor
.
instanceof
operatorvalue instanceof Constr
Checks the whole prototype chain. Always returns false for primitive operands. Throws an exception if rhs operand isn’t a function.
Identical to:
Constr.prototype.isPrototypeOf(value)
Pitfall: objects that aren’t instances of Object
don’t get identified as an object by instanceof
.
Pitfall: instanceof
might not work across different frames and windows, which each have their own global variables.
Workarounds:
Array.isArray()
postMessage( )
to copy over objects.constructor.name
Tips for implementing constuctors
Use strict mode to protect against forgetting to use new
. Strict mode will raise an exception:
TypeError: Cannot set property 'name' of undefined
Returning arbitrary objects from a constructor. JavaScript can return arbitrary objects, allowing you to use them as factory methods.
function Expression(str) {
if (...) {
return new Addition(..);
} else if (...) {
return new Multiplication(...);
} else {
throw new ExpressionException(...);
}
}
...
var expr = new Expression(someStr);
Avoid prototype properties with initial values
Do this instead to create a new property on the instance with a default value:
function Names(data) {
this.data = data || [];
}
When you might use prototype property with an initial value:
Lazy instantiation of properties
function Names(data) {
if (data) this.data = data;
}
Names.prototype = {
constructor: Names, // (1)
get data() {
// Define, don’t assign
// => avoid calling the (nonexistent) setter
Object.defineProperty(this, 'data', {
value: [],
enumerable: true,
configurable: false,
writable: false
});
return this.data;
}
};
Private Data in the Environment of a Constructor (Crockford Privacy Pattern)
Public properties
Constr.prototype.publicMethod = ...;
function Constr(...) {
this.publicData = ...;
...
}
Private values
function Constr(...) {
...
var that = this; // make accessible to private functions
var privateData = ...;
function privateFunction(...) {
// Access everything
privateData = ...;
that.publicData = ...;
that.publicMethod(...);
}
...
}
Privileged methods
function Constr(...) {
...
this.privilegedMethod = function (...) {
// Access everything
privateData = ...;
privateFunction(...);
this.publicData = ...;
this.publicMethod(...);
};
}
Private Data in Properties with Reified Keys
var StringBuilder = function () {
var KEY_BUFFER = '_StringBuilder_buffer';
function StringBuilder() {
this[KEY_BUFFER] = [];
}
StringBuilder.prototype = {
constructor: StringBuilder,
add: function (str) {
this[KEY_BUFFER].push(str);
},
toString: function () {
return this[KEY_BUFFER].join('');
}
};
return StringBuilder;
}();
Note the IIFE.
Keeping Global Data Private via IIFEs
Attaching private global data to a singleton object
var obj = function () { // open IIFE
// public
var self = {
publicMethod: function (...) {
privateData = ...;
privateFunction(...);
},
publicData: ...
};
// private
var privateData = ...;
function privateFunction(...) {
privateData = ...;
self.publicData = ...;
self.publicMethod(...);
}
return self;
}(); // close IIFE
Keeping global data private to all of a constructor
var StringBuilder = function () { // open IIFE
var KEY_BUFFER = '_StringBuilder_buffer_' + uuid.v4();
function StringBuilder() {
this[KEY_BUFFER] = [];
}
StringBuilder.prototype = {
// Omitted: methods accessing this[KEY_BUFFER]
};
return StringBuilder;
}(); // close IIFE
Attaching global data to a method
var obj = {
method: function () { // open IIFE
// method-private data
var invocCount = 0;
return function () {
invocCount++;
console.log('Invocation #'+invocCount);
return 'result';
};
}() // close IIFE
};
Utility function
function subclasses(SubC, SuperC) {
var subProto = Object.create(SuperC.prototype);
// Save `constructor` and, possibly, other methods
copyOwnPropertiesFrom(subProto, SubC.prototype);
SubC.prototype = subProto;
SubC._super = SuperC.prototype;
};
Inheriting Instance Properties
function Sub(prop1, prop2, prop3, prop4) {
Sub._super.call(this, prop1, prop2); // (1)
this.prop3 = prop3; // (2)
this.prop4 = prop4; // (3)
}
The trick is to not invoke Super
via new
.
Inheriting Prototype Properties / making instanceof
work for instances
Give sub.prototype
the prototype super.prototype
.
Sub.prototype = Object.create(Sub._super.prototype);
Sub.prototype.constructor = Sub;
Sub.prototype.methodB = ...;
Sub.prototype.methodC = ...;
Overriding a Method vs. Making a Supercall
Methods added to Sub.prototype
will override methods with the same name in Super.prototype
.
A home object of a method is the object that owns the property that contains the method.
To call a supermethod, skip the home object of the current method, search for a method with that name, and invoke with the current this
.
Sub.prototype.methodB = function (x, y) {
var superResult = Sub._super.prototype.methodB.call(this, x, y); // (1)
return this.prop3 + ' ' + superResult;
}
Example
Superconstructor
function Person(name) {
this.name = name;
}
Person.prototype.describe = function () {
return 'Person called '+this.name;
};
Subconstructor
function Employee(name, title) {
Person.call(this, name);
this.title = title;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.describe = function () {
return Person.prototype.describe.call(this)+' ('+this.title+')';
};
Just use the empty object {}
instead of Object.prototype
and []
instead of Array.prototype
.
Examples
> var arr1 = [ 'a', 'b' ];
> var arr2 = [ 'c', 'd' ];
> [].push.apply(arr1, arr2)
4
> arr1
[ 'a', 'b', 'c', 'd' ]
> Array.prototype.join.call('abc', '-')
'a-b-c'
> [].map.call('abc', function (x) { return x.toUpperCase() })
[ 'A', 'B', 'C' ]
> 'abc'.split('').map(function (x) { return x.toUpperCase() })
[ 'A', 'B', 'C' ]
> String.prototype.toUpperCase.call(true)
'TRUE'
> String.prototype.toUpperCase.call(['a','b','c'])
'A,B,C'
> var fakeArray = { 0: 'a', 1: 'b', length: 2 };
> Array.prototype.join.call(fakeArray, '-')
'a-b'
> var obj = {};
> Array.prototype.push.call(obj, 'hello');
1
> obj
{ '0': 'hello', length: 1 }
function logArgs() {
Array.prototype.forEach.call(arguments, function (elem, i) {
console.log(i+'. '+elem);
});
}
Array-Like Objects and Generic Methods
arguments
DOM node lists - returned by document.getElementsBy*()
Strings
Array-like objects need elements accessible by integer indices and a length
property. Array methods need these to be readable, and sometimes writable.
isNaN( x )
false
if value can be converted into a numbertrue
if it cannotWhen applied to objects, calls valueOf( )
method.
Number( x )
Input | Output |
---|---|
Boolean | true ->1; false ->0 |
Number | (passes through) |
null |
0 |
undefined |
NaN |
Strings
String | Output |
---|---|
numeric strings, no decimal | decimal integer |
floating point format | floating point |
hex format | hex |
empty | 0 |
anything else | NaN |
parseInt( x, radix )
Returns the first contiguous numeral string’s numerical value, ignoring the rest of the string.
parseFloat( x )
Will return the value of the the first valid contiguous numerical string in floating point format.
Trivia: bind(con)
will keep the new function bound to con
even when you attempt to use apply
or call
with a different context!
concat( )
will convert any non-string type into a string. For example, an Array ['a', 'b']
will be converted to 'a,b'
replace( )
character sequences
Sequence | Replacement Text |
---|---|
$$ |
$ |
$& |
Substring matching entire pattern |
$' |
Right context |
$` | Left context |
$n |
n th capture (0-9) |
$nn |
nn th capture (01-99) |
Data Properties
Attributes
[[Configurable]]
[[Enumerable]]
[[Writable]]
[[Value]]