JavaScript
Iterables
DATA TYPES
Number (decimals and whole numbers)
BigInt (x > +/- 2^53 -1 )
String
Boolean
Null (ie. let age = null;)
Undefined (ie. let age;)
Object (arrays etc...)
Symbols (unique identifiers for objects)
typeof xortypeof (x)returns a string with the name of the data type of x. For null, it returns "object".
INTERACTION
alert("Hello"); - shows a message and waits for the user to press "OK".
result = prompt(title, [default]); - input field for user and buttons OK/Cancel. title is text to show, default is optional 2nd argument for initial value for the input field. []'s around default means its optional. The input is stored into result.
result = confirm(question); - shows text question and has two buttons (Ok and Cancel) returns Boolean value.
TYPE CONVERSIONS
String Conversion - String(value);
Numeric Conversion - Number(value);
undefined becomes NaN, null becomes 0, true becomes 1, false becomes 0, empty strings are 0.
Boolean Conversion - Boolean(value);
0 null indefined Nan "" become false. Any thing other than previous is true.
BASIC OPERATORS
Operand - what operators are applied to (ie. 5 * 2 where 5 and 2 are operands and * is the operators)
Unary Operator - operator and single operand ( x = -x )
Unary + : doesn't do anything to numbers but if operand isn't a number, it converts it to a number (+true is 1, +"2" is 2 as a number.)
Prefix Form: ++a : returns new incremented value
Postfix Form: a++ : returns old value before increment
Binary Operator - operator and 2 operands ( x - y )
Other operators: +, -, *, /, %, ** exponents (2**3 = 8).
COMPARISONS
>,>=, <, <=, ==, !=
String Comparison - 'Z' > 'A' is true - compares lexicographical order where a is least Z is most in value.
Strict Equality : 0 == false is true b/c different types are converted to numbers by the equality operator
==. So an "" becomes 0 as does false.===is the strict equality operator which checks equality without type conversion.
IF-STATEMENT, ? OPERATOR
The if, if-else, and if-elseif-else is the same as in Java
? Operator
Used to assign something to a variable depending on a condition:
Multiple ?'s for >1 conditions:
LOGICAL OPERATORS
|| OR
Finds first truthy value:
result = value1 || value2 || value3;converts operands (value1/2/3) to Boolean and evaluates each from left to right one by one. If the operand istrue, stops and returns the original value of that operand. if all are false, returns last operand.
&& AND
Finds the first falsy value. same process as above. If all are true, returns the last operand.
! NOT
NULLISH COALESCING OPERATOR - ??
?? is the nullish coalescing operator; it treats null and undefined similarly and it's a nice syntax to get the first "defined" value of the two arguments.
a ?? b--> returns the first argument (a) if it's not null/undefined; otherwise returns b. It's basically:
Multiple ??'s:
LOOPS
while, do-while, for, switch, break/continue are all the same as in Java.
FUNCTIONS
Function Declaration
Default Parameters - if an actual parameter isn't provided, the formal parameter is undefined. To bypass this:
Return - same as in Java. If a function has an empty
returnor doesn't have it at all, it returnsundefined.
FUNCTION EXPRESIONS
In JS, functions aren't structures; they're actually a special kind of value which can be assigned; hence Function Expressions:
The function is created and assigned to the sayHi variable. You can even copy a function to another variable:
Differences b/n function expressions & declarations:
Function Declaration:
function, declared as a separate statement, in the main code flow.
visible in the whole script, no matter where it is; can be called earlier than it's defined.
Function Expression:
function, created inside an expression.
created when the execution reaches it and is usably only from that moment forward.
ARROW FUNCTIONS
There's another way to create functions besides declarations & expressions: Arrow Functions.
For a multiline expression, use {}'s and use a normal
returninside them:Arrow Functions:
Don't have
thisDon't have
argumentsCan't be called with
newDon't have
super
POLYFILLS
New language features may include not only syntax constructs and operators, but also built-in functions. Ie. some outdated JS engines don't have Math.trunc() so it can't run that code.
A polyfill is a script which updates/adds new functions. It "fills" in the gap and adds missing implementations. (core.js is good for this)
TRANSPILERS
A transpiler is a special piece of software that can parse ("read and understand") modern code, and rewrite it using older syntax constructs (the result would be the same). Usually, a developer runs the transpiler on their own computer, and then deploys the transpiled code to the server. Babel is one of the most used transpilers.
OBJECTS ; [python dictionary]
The
objectdata type is basically the python dictionary. It's created with {}'s and an optional list of propertiespropertyis a key-value pair.keyis a string (called name/identifier)valueis anything- OBJECT TO PRIMITIVE CONVERSION
When objects are added/subtracted (obj1 +/- obj2) or printed, objects are auto-converted to primitives, then the operation is carried out.
Objects are
truein boolean, and there are only numeric and string conversionsNUMERIC CONVERSION- happens when you apply math functions on objects. ie.Dateobjects (from datetime) can be substractedSTRING CONVERSION- happens when you output an object like alert(obj), etc...ToPrimitive
There are 3 variants of type-conversion, each called a "hint":
Object-to-String
Object-to-Number
Default - when operator is "not sure" what type to expect (ie. a + can concatenate sting && add nums)
Symbol.toPrimitive
Object.keys, .values, .entries
- SYMBOL type
Object property keys can be either Strings or Symbols.
A Symbol is a unique value; It's created using
Symbol();HIDDEN PROPERTIES - symbols allow us to create hidden properties of an object that can't be accidentally access or overwrite. Symbols are skipped by
for-inloops andObject.keys(objectName)methodGLOBAL SYMBOLS
Sometimes, you want same-names symbols, perhaps different parts of your application want to access symbol "id"- exactly the same property. That's where the global symbol registry steps in. You can create symbols in it and access them later.
In order to read a symbol from the registry, use
Symbol.for(key). This returns the symbol with the symbol name/description/label of key- otherwise, it creates a new symbolSymbol(key)and stores it:
NUMBER
STRING
Concatenation
Length
Finding String in a String
Substring (str.slice, str.substring, str.substr)
Replacing String Content
replaces specified value with another value in a string. It doesn't change the string, it returns a new string. It only replaces first match and is case sensitive.
Upper and Lower Cases
Trim
Converting String to Array
String interpolation (kinda like printf)
Special Characters
Loop Over characters with For-of Loop
Test for Match (includes, startsWith, endsWith)
ARRAYS
Creating an array
Access Elements
Adding Elements
Difference b/n Arrays & Objects: arrays use numbered indexes, while, Objects use names indexes.
Removing Elements
Changing Elements and Copying Array
Length (bit tricky)
Properties & Methods
Iteration
Multi-Dimensional Array
.map()
allows you to run a function on each item in the array, returning a new array as the result
In React,
map()can be used to generate lists
MAP
Basically an object (or python Dictionary) but Map allows keys of any type.
Methods and Properties:
Basic Implementation:
Map can also use Objects as Keys:
Iteration
SET
“set of values” (without keys), where each value may occur only once
Methods & Properties:
Basic Implementation:
Iteration over Set:
WeakMap
is
Map-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means.
WeakSet
is
Set-like collection that stores only objects and removes them once they become inaccessible by other means. [WeakMap&Set]'s main advantages are that they have weak reference to objects, so they can easily be removed by garbage collector. That comes at the cost of not having support forclear,size,keys,values…
DESTRUCTURING ASSIGNMENT
Destructuring assignment is a special syntax that allows us to “unpack” arrays/objects into a bunch of variables.
- Object Destructing
Basic Syntax: let {var1, var2} = {var1:…, var2:…}
The right side is an existing object. The left side contains an object-like “pattern” for corresponding properties (same name as property names in object):
If we want to assign a property to a variable with another name, set the variable name using a colon:
The Rest "..."
DATE AND TIME
new Date object:
Access date components from Date object:
Autocorrection (Out-of-range date components are distributed automatically)
Date.now() - returns the current timestamp
Date.parse() from a string
JSON
Let’s say we have a complex object, and we’d like to convert it to a string, to send it over a network, or just to output it for logging purposes. Throughout development, properties are added, renamed, and removed; updating a toString() every single time is PAIN.
JSON (JavaScript Object Notation)is a general format to represent values/objects.- JSON.stringify
converts objects into JSON to a string called
encoded/serialized/stringified/marshalledobject.Note: JSON-encoded object differs from the object literal in that:
Strings use
"". No''or backticks in JSON. So'John'-->"John".All Object property names are
"". Soage:30-->"age":30.JSON.stringifycan be applied to str, numbers, bool,null, & even arrays:JSON is a data-only language-independent specification, so some JS-specific object properties are skipped by
JSON.stringify: functions, symbolic keys and values, and properties that storeundefined:
REST PARAMETERS
A function can be called with any number of arguments, no matter how it is defined:
The rest of the unused parameters can be included in the function definition by using three dots
...followed by the name of the array that will contain them:We can choose to get the first parameters as variables, and gather only the rest. Here below, the first 2 arguments go into variables, and the rest go into a 'titles' array:
Spread Syntax
In Rest Parameters, we saw how to get an array from the list of parameters. But sometimes we need to do the opposite.
Ie. Math.max() returns the greatest number from a list. Let's say we have an array [3, 5, 1]. You can't pass the array into the function as it expects numeric arguments, and doing Math.max(arr[0], arr[1], etc..) may take forever.
Spread Syntaxworks similarly with rest parameters, also using..., but inversely. When ...arr is used in a function call, it expands the iterable object into the list of arguments:We can also use Spread Syntax to merge arrays:
GLOBAL OBJECTS
The Global object provides variables & functions that are available anywhere. In a browser it's named
window. for Node.js it'sglobal, and recently,globalThis(use this now).In a browser, global functions & variables declared with
var(notlet/const) become the property of the global object:If a value is so important that you’d like to make it available globally, write it as a property:
For some reason, this works instead of the above:
NFE : Named Function Expression
In JS, functions are objects, kinda like: "action objects"
The "name" property:
The "length" property:
NFE
You can also call
sayHi()internally and it would work, the problem is thatsayHimay change outside. If the function gets assigned to another variable instead, the code will start to give errors:
Function Binding
When passing object methods as callbacks, there’s a known problem: "losing
this".ie. Here’s how it may happen with
setTimeout:Solution: a Wrapper (also called wrapping function):
PROPERTY FLAGS AND DESCRIPTORS
Object properties, besides a
value, have three special attributes (“flags”):writable– iftrue, the value can be changed, otherwise it’s read-only.enumerable– iftrue, then listed in loops, otherwise not listed.configurable– iftrue, the property can be deleted and these attributes can be modified, otherwise not.All 3 are initially
true, but they can be changed. To access the full info about a property: (returns a "property-descriptor" object: value and all the flags)Basic Implementation
To change the flags: use the
Object,definePropertymethod:Basic Implementation of Writable:
Basic Implementation of Enumberable:
Basic Implementation of Configurable:
Define many properties with Object.defineProperties:
PROPERTY GETTERS + SETTERS
There are 2 kinds of object properties:
data properties,accessor properties.Accessor properties are essentially properties used to get and set a value. In an object literal, they're denoted by
getandset:Basic implementation:
You can also create accessor properties, get&set, via defineProperty descriptor:
PROTOTYPAL INHERITANCE
Java Inheritance (extending one object to another, to access object properties)
[ [ Prototype ] ]
Objects have a special hidden property [[Prototype]] ; either null or references another object. This object is called a "prototype".
When we read a property from
object, and it’s missing, JavaScript automatically takes it from the prototype. This isPrototypal Inheritence.The property
[[Prototype]]is internal and hidden. One way to set it is:__proto__:
So if
animalhas a lot of useful properties and methods, then they become automatically available inrabbit. Such properties are called “inherited”:You can have as many prototypes as you want, and you can chain them: if duck inheritis from rabbit inherits from animal, then duck can also inherit from animal.
For-in loop
If
rabbitinherits fromanimal, a call to Object.keys(rabbit) will only return the keys ofrabbit. But, if you use a for-in loop, it iterates over it's own and inherited keys:
Prototype methods, objects without __proto__
__proto__The
__proto__is considered outdated; the modern methods are:Object.create(proto, [descriptors])– creates an empty object with givenprotoas[[Prototype]]and optional property descriptors.Object.getPrototypeOf(obj)– returns the[[Prototype]]ofobj.Object.setPrototypeOf(obj, proto)– sets the[[Prototype]]ofobjtoproto
Object.create's optional second argument:
Other Methods:
Object.keys(obj),Object.values(obj),Object.entries(obj)returns an array of property names/values/key-value pairs.Object.getOwnPropertySymbols(obj)- returns an array of all keys with Symbols.Object.getOwnPropertyNames(obj)- returns an array of all own string keys.Reflect.ownKeys(obj)- returns an array of all keys (basically same as ^).obj.hasOwnProperty('keyName')- returns boolean if obj has own (not inherited) key named keyName.
F.PROTOTYPE
Remember, new objects can be created with a constructor function like
new F(). So ifF.prototypeis an object, then thenewoperator uses it to set[[Prototype]]for the new object.F.prototypehere is a regular property onF. Ie:
NATIVE PROTOTYPES
All built-in objects follow the same pattern:
The methods are stored in the prototype (Array.prototype, Object.prototype, etc...)
The object itself stores only the data (array items, object properties, etc...)
CLASSES
We often need to create many objects of the same kind (ie. users).
A class is kind of like template code for creating objects, providing initial values for variables and methods.
General Syntax:
In JS, a
classis a a function (typeof myClass >>> function). Afternew classNameobject is created, when we call its method, it’s taken from the prototype.
Class Expression
Just like functions, classes can be defined inside another expression, passed around, returned, assigned, etc:
Getters/Setters
Just like literal objects, classes may include getters/setters:
CLASS INHERITANCE - way for one class to extend another class.
Extends
To extend a child class to a parent,
class Child extends Parent:
Overriding methods
If both Parent and Child classes share a method name, a call from a Child class object will call the Child class method.
"Super"
If you want to intentionally call the Parent method instead of overriding, then call
super.methodName(). However, arrow functions don't have asuperkeyword.
Overriding Constructors
A call to
super(...)will call the Parent constructor (only from inside the child constructor).If a Child extends a Parent and has no
constructor, then it calls the Parent constructor passing it all the arguments.NOTE: You can override both methods, but also class fields (methods+variables).
STATIC PROPERTIES AND METHODS
Static properties and methods are inherited
PRIVATE+PROTECTED PROPERTIES AND METHODS
properties and methods are split into two groups:
Internal interface – methods+properties, accessible from other methods of the class, but not from the outside.
External interface – methods+properties, accessible also from outside the class
Public vs. Private Fields (properties+methods):
Public: accessible from anywhere. They comprise the external interface.
Private: accessible only from inside the class. These are for the internal interface.
#prefix ie. #name or #returnName(){...}
Protected: like private, but child classes can access. These fields will be read-only. JS doesn't have an actual implementation but you can emulate it by a class having a getter but not a setter.
_prefix ie. _name or _returnName(){...}
Ie. a Name Class:
EXTENDING BUILT-IN CLASSES
You can extend a given class onto built-in classes, like Array/Map, and add functionality:
Ie. extend a custom PowerArray class to the built-in Array class:
CLASS CHECKING: "instanceof"
The
instanceofoperator allows to check whether an object belongs to a certain class. It also takes inheritance into account. The syntax is:It also works with constructor functions:
Object.prototype.toString
We can use
toStringas an extendedtypeofand an alternative forinstanceof. It will return:For a number, it will be
[object Number]For a boolean, it will be
[object Boolean]For
null:[object Null]For
undefined:[object Undefined]For arrays:
[object Array]…etc (customizable).
MIXINS
In JS we can only inherit from a single object & a class can only extend one other class.
A mixin is a class containing methods that can be used by other classes without a need to inherit from it.
The simplest way to implement a mixin in JS is to make an object with useful methods, so that we can easily merge them into a prototype of any class.
ie. here the mixin sayHiMixin is used to add some “speech” for User:
ERROR HANDLING
The try-catch syntax is same as in Java:
Error Object
When an error occurs, JS generates an object containing the details about it. The object is then passed as an argument to
catch:the error object has two main properties:
name- Error name. For instance, for an undefined variable that’s"ReferenceError".message- Textual message about error details.
There are other non-standard properties available in most environments. One of most widely used and supported is:
stack- Current call stack: a string with info about the sequence of nested calls that led to the error.
ie:
Throwing our own errors
Let's say we have a JSON and we are parsing it. What if the
jsonis syntactically correct, but doesn’t have a requirednameproperty?
'Throw' operator
The
throwoperator generates an error. The syntax is:JS has many built-in constructors for standard errors:
Error,SyntaxError,ReferenceError,TypeError, etc... We can use them to create error objects:Implementation of try-catch and throw operator:
Try-Catch-Finally
CALLBACKS
A callback is a function that's passed into another function and is to be executed after another function has finished executing.
Function Sequence
JS functions are executed in the sequence they are called. Not in the sequence they are defined. ie:
Callback Function
Let’s add a
callbackfunction as a second argument (usually anonymous) toloadScriptthat should execute when the script loads.Using a callback, you can call
myCalculatorwith a callback, and let the calculator function run the callback after the calculation is finished.Right: myCalculator(5, 5, myDisplayer);
Wrong: myCalculator(5, 5, myDisplayer());
Callback in Callback
ie. We can load two scripts sequentially: the first one, and then the second one after it, by putting the second callback call inside the first callback:
Callback Error handling
ie. In the case the script loading fails, the callback need to react to the error. The error handling usage:
The first argument of the callback is actually reserved for an error if it occurs.
PROMISES
"Producing code" - code that does something and takes time. ie. code that loads the data over a network
"Consuming code" - code that wants the result of the “producing code” once it’s ready. ie. Functions
A Promise - a JavaScript object that links producing code and consuming code
Constructor Syntax
executor- function passed tonew Promise. "Producing Code"resolve/reject- callbacks provided by JS itself. When the executor obtains the result, it should call one of these callbacks:resolve(value)— if the job is finished successfully, with resultvalue.reject(error)— if an error has occurred,erroris the error object.
The
promiseobject returned by thenew Promiseconstructor has these internal properties:stateinitially
"pending", then changes to either"fulfilled"whenresolveis called or"rejected"whenrejectis called.
resultinitially
undefined, then changes to eithervaluewhenresolve(value)is called orerrorwhenreject(error)is called.
ie:
Note: there can only be one call to resolve/reject in the executor. All other resolve/reject calls below the first one are ignored.
Consumers: then, catch, finally
The state and result properties of the Promise object are internal. We can’t directly access them. We have to use the methods
.then/.catch/.finallythen
The 1st argument of
.thenis a function that runs when the promise is resolved, and receives the resultThe 2nd argument of
.thenis a function that runs when the promise is rejected, and receives the error
ie.
catch
If we’re interested only in errors, then we can use
nullas the first argument:
.then(null, errorHandlingFunction)Or we can use
.catch(errorHandlingFunction), which is exactly the same:
finally
Just like there’s a
finallyclause in a try-catch there’sfinallyin promises.The call
.finally(f)is similar to.then(f, f)in the sense thatfalways runs when the promise is settled: be it resolve or reject.It's a good handler for performing cleanup ie. stopping our loading indicators (not needed anymore regardless of outcome)
ie:
Promise Chaining
Here the flow is:
The initial promise resolves in 1 second
(*),Then the
.thenhandler is called(**).The value that it returns is passed to the next
.thenhandler(***)…and so on.
Last updated