-
JavaScript is a cross-platform, object-oriented scripting language used to make webpages interactive (e.x. having complex animations, clickable buttons, popup menus, etc.). There are also more advanced server side versions of javascript such as Node.Js which allow you to add more functionality to a website than simply downloading files (such as realtime collaboration between multiple computers).
-
JavaScript is case-sensitive and uses the Unicode character set.
-
In JavaScript, instructions are called statements (it is a line of code commanding a task. Every program consists of a sequence of statements.) and are separated by semicolons
;. -
The source text of JavaScript script gets scanned from left to right and is converted into a sequence of input elements which are tokens, control characters, line terminators, comments, or whitespace. Spaces, tabs, and newline characters are considered whitespace.
-
Comments:
Comments behave like whitespace and are discarded during script execution.
// a one line comment /* this is a longer, * multi-line comment */
-
Identifier:
A sequence of characters in the code that identifies a variable, function, or property.
-
In JavaScript, identifiers can contain only alphanumeric characters (or
$or_), and may not start with a digit. -
Declarations:
There are three kinds of declarations in JavaScript.
-
varDeclares a variable, optionally initializing it to a value.
-
letDeclares a block-scoped, local variable, optionally initializing it to a value.
-
constDeclares a block-scoped, read-only named constant.
-
-
A variable declared using the
varorletstatement with no assigned value specified has the value of undefined. -
A constant cannot change value through assignment or be re-declared while the script is running. It must be initialized to a value. However, the properties of
objectsorarrayassigned to constants are not protected (i.e. We can change the value inside the object or array). -
The
undefinedvalue behaves asfalsewhen used in a boolean context. -
The
undefinedvalue converts toNaNwhen used in numeric context.var a; // a is undefined a + 2; // return NaN
-
When you evaluate a
nullvariable, thenullvalue behaves as0in numeric contexts and asfalsein boolean contexts. -
When you declare a variable outside of any function, it is called a global variable, because it is available to any other code in the current document.
-
When you declare a variable within a function, it is called a local variable, because it is available only within that function.
-
Hoisting: Variables in JavaScript are in a sense "hoisted" or lifted to the top of the function or statement. Variables that are hoisted return a value of
undefined. -
Because of hoisting, all
varstatements in a function should be placed as near to the top of the function as possible. This best practice increases the clarity of the code. -
In ECMAScript 2015 (ES6),
let(const) does not hoist the variable to the top of the block. Referencing the variable in the block before the variable declaration results in aReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.console.log(x); // ReferenceError let x = 3;
-
For functions, only the function declaration gets hoisted to the top and not the function expression.
-
Global variables are in fact properties of the global object. In web pages, the global object is window, so you can set and access global variables using the
window.variablesyntax. -
JavaScript is a dynamically typed language. That means you don't have to specify the data type of a variable when you declare it, and data types are converted automatically as needed during script execution.
-
A regex literal is a pattern enclosed between slashes.
-
Conditional statements:
A conditional statement is a set of commands that executes if a specified condition is true. JavaScript supports two conditional statements:
if...elseandswitch. -
Falsy values:
A falsy value is a value that translates to false when evaluated in a Boolean context.
The following values evaluate to false (also known as Falsy values):
falseundefinednull0NaN- the empty string (
"")
-
Do not confuse the primitive boolean values true and false with the true and false values of the Boolean object. For example:
var b = new Boolean(false); if (b) // this condition evaluates to true if (b == true) // this condition evaluates to false
-
Exception handling statements:
You can throw exceptions using the
throwstatement and handle them using thetry...catchstatements. -
You can use a
catchblock to handle all exceptions that may be generated in thetryblock.try { throw 'myException'; // generates an exception } catch (e) { // statements to handle any exceptions logMyErrors(e); // pass exception object to error handler }
-
The
finallyblock contains statements to execute after the try and catch blocks execute but before the statements following thetry...catchstatement. Thefinallyblock executes whether or not an exception is thrown. If an exception is thrown, the statements in thefinallyblock execute even if nocatchblock handles the exception.openMyFile(); try { writeMyFile(theData); //This may throw an error } catch(e) { handleError(e); // If we got an error we handle it } finally { closeMyFile(); // always close the resource }
-
If the
finallyblock returns a value, this value becomes the return value of the entiretry-catch-finallyproduction, regardless of anyreturnstatements in thetryandcatchblocks. -
Overwriting of
returnvalues by thefinallyblock also applies to exceptions thrown or re-thrown inside of thecatchblock. -
Promises:
A Promise is in one of these states:
- pending: initial state, not fulfilled or rejected.
- fulfilled: successful operation
- rejected: failed operation.
- settled: the Promise is either fulfilled or rejected, but not pending.
-
The difference between a
for...ofloop and afor...inloop - Whilefor...initerates over property names,for...ofiterates over property values. -
Function:
Functions are one of the fundamental building blocks in JavaScript. A function is a JavaScript procedure — a set of statements that performs a task or calculates a value.
Simple Function to calculate the factorial:
var factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1); }; console.log(factorial(3));
-
Recursive function:
A function that calls itself is called a recursive function.
-
A function can refer to and call itself. There are three ways for a function to refer to itself:
- the function's name
arguments.callee- an in-scope variable that refers to the function
For example, consider the following function definition:
var foo = function bar() { // statements go here };
Within the function body, the following are all equivalent:
bar()arguments.callee()foo()
-
Syntax Parser:
A program that reads your code and determines what it does and if its grammar or syntax is valid.
-
Lexical Environment:
Where something sits physically in the code you write.
-
Execution Context:
The wrapper which help to manage the code that is running. There are lots of lexical environments. Which one is currently running is managed via execution contexts.
-
Name/Value Pair:
A name which maps to a unique value. The name may be defined more than once, but only can have one value in any given context. That value may be more name/value pairs.
-
Object:
A collection of name-value pairs.
// Example of an object let address = { street: 'Main', number: 100, apartment: { floor: 3, number: 301 } }
-
Execution context (Global):
- Execution context (Global) creates two things: Global Object (
windowis case of browsers) and special variable calledthis. - Its been created by javascript engine.
- Each window/tab has its own global execution context.
- At global level, global object (
window) is equal tothis. - Execution context is created in two phases: Creation Phase and Execution Phase
- In Creation Phase, Global Object,
this, Outer environment and Hoisting are created. - In Creation Phase, Parser runs through the code and begins to setup translations such as where we have created variables or functions and setup memory space for variables and functions. This is called 'Hoisting'.
- Execution context (Global) creates two things: Global Object (
-
All variables in javascript are initially set to undefined by javascript engine.
-
undefined is a special keyword or value in javascript. Its also one of a data type in javascript. It is assigned to a variable which is declared but not defined by javascript engine.
-
Defining a variable with undefined is a bad practice and should be avoided.
Example:
var a; console.log(a); if (a === undefined) { // undefined is a keyword console.log('a is undefined!'); } else { console.log('a is defined!'); }
-
In Execution Phase, code is executed line by line.
-
Single Threaded:
It means one command is executed at a time.
-
Synchronous:
One line of code is executed at a time in order.
-
Javascript is a Single Threaded and Synchronous execution in behavior.
-
Invocation:
Running or calling a function. In Javascript, a function is invoked using parenthesis
().Example:
function b() { } function a() { b(); } a();
Steps involved in execution:
- Firstly Global Execution Context is created.
- In Creation Phase, Global Object('window'), 'this' and setup memory space for function.
- In Execution Phase, Code is executed line by line.
- When it reached the line
a(), a new execution context is created and placed on the top of Execution Stack. Then it run that code. - Now when it reaches the line
b(), a new execution context is created and placed on top on thea()execution context. Then it run that code. - Then
b()is executed and popped-off the execution stack. - Similarly,
a()is executed and popped-off the execution stack.
-
Every function creates a new execution context and placed on top of the execution stack. When function is finishes execution, its popped-off the execution stack.
-
Variable Environment:
Where the variables live and how they relate to each other in memory. Each variable live in its own execution context.
Example:
// Each variable live in its own execution context. function b() { var myVar; console.log(myVar); // output: undefined } function a() { var myVar = 2; console.log(myVar); // output: 2 b(); } var myVar = 1; console.log(myVar); // output: 1 a(); console.log(myVar); // output: 1
-
Every execution context has a reference to its outer environment.
-
Scope chain: lexical environment top to bottom. Outer reference that any running function has.
Example:
// Example 1: // Here `b()` and `a()` are lexically sitting in the global environment. function b() { console.log(myvar); // output: 1 // Every execution context has a reference to its outer environment. // Here outer lexical environment refers to Global execution context. } function a() { var myVar = 2; b(); } var myVar = 1; a();
// Example 2: // Here `b()` is lexically sitting in the `a()` lexical environment. // and `a()` is lexically sitting in the global lexical environment. function a() { function b() { console.log(myvar); // output: 2 // Here outer lexical environment refers to a() execution context. } var myVar = 2; b(); } var myVar = 1; a();
-
Scope:
Where a variable is available in the code.
-
In ES6,
letis used to declare the variable. It allows the javascript engine to use block scoping, Which means scope of a given variable is only bound to a given block of code. In execution phase, variable is placed in memory however we are not allowed to use it outside its block. -
Asynchronous:
More than one at a time. Multiple piece of code executing at the same time.
-
In browser, The javascript engine talks with the Rendering Engine which is outside the javascript engine. Rendering engine prints or renders the contents on the screen. This communication between the Rendering engine and Javascript engine is asynchronous in nature. Whereas whats happening inside the javascript engine is synchronous execution.
-
Javascript Engine has list/queue to manage the events called Event Queue. Every event is placed on this queue when its called.
-
Javascript Engine looks for Event Queue after every execution context is popped-off the execution stack. Then when the execution stack is empty, events are processed from the Event Queue. For each event a new execution context is created on the execution stack.
-
Browser places every event in Event Queue asynchronously. Whereas Javascript engine execute it one by one synchronously.
-
Long running functions interrupts the event calls. As the execution stack is not empty, the event are not processed.
-
Dynamic Typing:
We don't specify the javascript engine what type of data a variable should hold, instead its been figured out while the code is running/executing. Variables can hold different types of values because it's all figured out during execution.
-
Javascript is Dynamically Typed. It means that there is no keyword in javascript to tell which type of variable is it.
-
Javascript determines the variable type at the time of execution.
-
Primitive Types:
A type of data that represents a single value.
There are 6 Primitive types in javascript:
-
undefined: It represents lack of existence. It shouldn't be set/assigned to a variable.
-
null: It also represents lack of existence. It can be set/assigned to a variable. Because JavaScript is case-sensitive, null is not the same as Null, NULL, or any other variant.
-
Boolean: It represents the values such as
trueorfalse. -
Number: In javascript, it always represent to a floating point numbers(numbers with decimals)
-
String: It is a sequence of characters enclosed in single or double quotes.
-
Symbol: Its used in ES6 and next version. Its not fully supported by older browsers. It is a data type whose instances are unique and immutable.
-
-
Operators:
A special function that is syntactically (written) differently. Generally, operators take two parameters and return one result.
-
Operators uses infix notation. Eg: 3
+4 -
Infix notation is the notation commonly used in arithmetical and logical formulae and statements. It is characterized by the placement of operators between operands - "infixed operators" - such as the plus sign in 2
+2. -
Operator Precedence:
Which operator function gets called first. Functions are called in order of precedence. If more than one operators are present, the operator with higher precedence is called first.
-
Associativity:
In what order operator functions get called in: left-to-right or right-to-left, when two or more operator functions have the same precedence. Left-to-Right is called Left Associativity and Right-to-Left is called Right Associativity.
Read more on operator precedence and associativity
Example:
var a = 2, b = 3, c = 4; a = b = c; // Assignment operator has right-to-left associativity console.log(a); // output: 4 console.log(b); // output: 4 console.log(c); // output: 4
-
Coercion:
Converting a value from one type to another.
Example:
// Coercion var a = 1 + '2'; console.log(a); // output: 12 console.log(3 < 2 < 1); // output: true Number(undefined); // NaN Number(null); // 0 Boolean(undefined); // false Boolean(null); // false Boolean(""); // false Boolean(0); // false
-
Its good practice to use
===instead of==for equality check. In case of==, coercion occurs if it is comparing different data type. Whereas in===, coercion doesn't occur. -
===will return true on comparison only if the RHS of operator has same value and data type as the LHS of the operator. -
Default Value:
Example:
// In ES5 function greet(name) { name = name || 'default value'; console.log('Hello ' + name); // Hello default value } greet();
-
Framework or Library is grouping of javascript code that performs a task and is intended to be reuseable.
-
Object can have properties and methods. i.e, A object can have a Primitive property, Object property and Function method. Object is sitting in memory and will have references to the addresses/spaces in memory of its properties and method.
-
Object is said to have
- property - if its value is Primitive
- method - if its value is Function.
-
Functions inside an object is called as method.
-
Computed member access operator is used to created new properties or methods for the object.
-
dot operator or member access operator is also used to created new properties or methods for the object.
var person = new Object(); person["firstName"] = "Syed"; // Computed member access operator person.lastName = "Pasha"; // dot operator/member access operator
-
JavaScript is case-sensitive and uses the Unicode character set.
-
An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces (
{}). -
Namespace:
A container for variables and functions. Typically to keep variables and functions with the same name separate.
Example:
var greet = 'Hello!'; var greet = 'Hola!'; console.log(greet); // output: Hola! // Collision or overriding of variables occurs here var english = {}; // Object literal syntax var spanish = {}; english.greet = "Hello!"; spanish.greet = "Hola!"; // here greet value doesn't collide or override by the same variable name // here 'english' and 'spanish' act as container for the greet variable console.log(english);
-
JSON (JavaScript Object Notation) is inspired by the object literal syntax. Here the property values must be enclosed in quotes. Technically, JSON is a subset of object literal syntax.
-
In Javascript,
JSON.stringify()is used to convert object to JSON andJSON.parse()is used to convert JSON to object.// Example of JSON { "firstName": "Syed", "isAProgrammer": true }
var objectLiteral = { firstName: 'Syed', isAProgrammer: true } console.log(JSON.stringify(objectLiteral)) // JSON.stringify() convert object into JSON
-
First Class Functions:
Everything you can do with other types you can do with functions. We can assign them to variables, pass them around as parameters to other functions, create them on the fly. Functions are special type of object in javascript. We can attach properties and methods to a function such as Primitive, Object and Function.
-
In Javascript, Functions are object.
-
In Javascript, Function object has some hidden special properties such as
- Name: Optional property - A function can have name or it can be anonymous (function without name).
- Code: its the actual line of code which we have written sit. It can be invocable (run this piece of code).
Example:
// Functions are object function greet() { console.log('Hi'); } // This function has properties: // Name: 'greet' // Code: console.log('Hi'); greet.language = 'english'; console.log(greet); // output: function greet() { console.log('Hi');} console.log(greet.language); // output: english
-
Expression:
A unit of code that results in a value. An expression return a value.
-
Statement:
A unit of code that doesn't results in a value. Statement doesn't return a value.
-
Function Expression aren't hoisted. Only variable and function declaration are hoisted.
// Function Statement function greet() { console.log('Hi'); } greet(); // Function Expression var anonymousGreet = function() { console.log('Hi'); } anonymousGreet(); // ----------------------- function log(a) { a(); } // Passing a function as parameter - First Class Function // Function Expression log(function() { console.log('Hi'); });
-
By Value:
All primitive types interact by value.
var a = 3; // 'a' has some primitive value & is stored in a memory location. var b = a; // Here value of 'a' is been copied to 'b', which is stored in some other location (other then 'a' location). a = 2; // change in value of 'a' does not affect the 'b' console.log(a); // output: 2 console.log(b); // output: 3
-
By Reference:
All objects including functions interact by reference.
var a = { greeting: 'Hi' }; // here 'a' is an object & is stored in a memory location. var b = a; // Here 'b' points to the same memory location of 'a'. No new object is created. a.greeting = 'Hello' // mutate console.log(a); // output: { greeting: 'Hello'}; console.log(b); // output: { greeting: 'Hello'}; // -------------------------------- // by reference (even as parameters) function changeGreeting(obj) { obj.greeting = 'Hola'; // mutate } changeGreeting(b); console.log(a); // output: { greeting: 'Hola'}; console.log(b); // output: { greeting: 'Hola'}; // -------------------------------- // Equals operator sets up new memory space (new address) // This is a special case where by references doesn't apply a = { greeting: 'Howdy' }; // Here new memory location was setup for 'a' // 'a' pointing to different spot in memory in this case console.log(a); // output: { greeting: 'Howdy'}; console.log(b); // output: { greeting: 'Hola'};
-
Mutate:
To change something.
-
Immutable:
It means it can't be changed.
-
this:
function a() { console.log(this); // Here 'this' points to global window object this.newVariable = 'hello'; // variables can be defined in global window object } var b = function() { console.log(this); // Here 'this' points to global window object } a(); console.log(newVariable); // assigned variable can be used without this operator b(); var c = { name: 'value', log: function() { this.name = 'Updated value'; // this will mutate the 'name' value console.log(this); // output: {name: 'Updated value',log: function() {console.log(this);}} // Here 'this' points to the 'c' object // It points to the object contains 'this' var setName = function(newName) { this.name = newName; // this will not mutate the 'name' property of 'c' object, instead this will mutate the 'name' variable in global window object. } setName('Updated Again!'); console.log(this); // output: 'Updated value' } } c.log();
// The quirk can be avoided like this var c = { name: 'value', log: function() { var self = this; // assigning the reference of 'this' to a variable self.name = 'Updated value'; // this will mutate the 'name' value console.log(self); // Here 'this' points to the 'c' object var setName = function(newName) { self.name = newName; // this will mutate the 'name' property of 'c' object, not the global window object. } setName('Updated Again!'); console.log(self); // output: 'Updated Again!' } } c.log();
-
Arrays:
Its a collection of same or different type of data.
// This is a valid array in javascript var arr = [ 1, false, { name: 'Syed' }, function(name) { var greeting = 'Hello '; console.log(greeting + name); }, "hello" ]; arr[3](arr[2].name); // output: 'Hello Syed'
-
A new execution context is created for any function, which will have 'Variable Environment', 'this', 'Outer Environment' and 'arguments'.
-
Arguments:
The parameters that are passed to a function. arguments is a keyword which contains all the value or the parameters passed to a functions.
function greet(firstname, lastname, language) { if (arguments.length === 0) { console.log('Missing Parameters!'); return; } console.log(firstname); console.log(lastname); console.log(language); console.log(arguments); console.log(arguments[0]) console.log('---------'); } greet(); greet('Syed'); greet('Syed', 'Pasha'); greet('Syed', 'Pasha', 'English');
-
Function Overloading:
Function with a same name has different number of parameters. It doesn't work in javascript as functions are object.
function greet(firstname, lastname, language) { language = language || 'en'; if (language === 'en') { console.log('Hello ' + firstname + ' ' + lastname); } if (language === 'es') { console.log('Hola ' + firstname + ' ' + lastname); } } function greetEnglish(firstname, lastname) { greet(firstname, lastname, 'en'); } function greetSpanish(firstname, lastname) { greet(firstname, lastname, 'es'); } greetEnglish('Syed', 'Pasha'); greetSpanish('Syed', 'Pasha');
-
Syntax Parsers reads the code character by character using a set of rules (valid syntax). It happens before the code is executed.
-
Its recommended to put semicolon at the end of a line of code. If there is no semicolon is present, the syntax parser will automatically insert semicolon, which can lead to unexpected behavior.
function getPerson() { return // Here Syntax parser will automatically insert semicolon { firstname: 'Syed' } } console.log(getPerson()); // output: undefined
-
Whitespace: Invisible characters that create literal 'space' in the written code.
-
Immediately Invoked Function Expressions (IIFE)s:
Immediately invoking a function expression.
// Example 1: var greeting = function(name) { console.log('Hello ' + name); }('Syed'); console.log(greeting); // output: 'Hello Syed' // Example 2: // Function statements can be used without function name // () will trick the syntax parser to treat it as function expression (function (name) { var greeting = 'Hello'; console.log(greeting + ' ' + name); }('Syed'));
-
Below code execution of (IIFE) under the hood:
- Firstly global execution context is created and the function object is placed in global execution context.
- The when the functions is invoked, a new execution context is created. The variables defined inside the function will sit in the execution context of its function and not in global execution context.
(function (name) { var greeting = 'Hello'; console.log(greeting + ' ' + name); }('Syed'));
// We can modify the global variable inside an IIFE, if we pass the global window object as parameter to the IIFE var greeting = 'Hola'; (function (global, name) { var greeting = 'Hello'; global.greeting = 'Hello'; console.log(greeting + ' ' + name); // output: Hello Syed }(window, 'Syed')); console.log(greeting); // output: Hello
-
Closures:
function greet(whattosay) { return function(name) { console.log(whattosay + ' ' + name); } } greet('Hi')('Syed'); // or var sayHi = greet('Hi'); sayHi('Syed');
Steps:
- When this line
var sayHi = greet('Hi');is executed, a new execution context is created for thegreetfunction. And a new variablewhattosayis setup in the variable environment. And the function in returned to variablesayHi. Thegreetfunction execution context is popped-off the execution stack. - Then this line
sayHi('Syed')is executed. Then a new execution context is created forsayHifunction.whattosayvariable is looked up in the scope chain where that variable is created (outer lexical environment reference).
Function (execution context) which has reference to variables in its outer lexical environment. Execution context is closed in its outer variables to which it has reference even after the execution context is popped-off the execution stack. This phenomenon of closing in all the variables(free variables) that it suppose to have access to is called Closure. This is the feature of javascript language.
// Example of closure function buildFunctions() { var arr = []; for (var i = 0; i < 3; i++) { arr.push(function() { console.log(i); } ) // arr.push((function(j) { // return function() { // console.log(j); // } // }(i)) // ) } return arr; } var fs = buildFunctions(); fs[0](); // output: 3 fs[1](); // output: 3 fs[2](); // output: 3
- When this line
-
Function Factories: A function which return or make other things.
function makeGreeting(language) { return function (firstName, lastName) { if (language === 'en') { console.log('Hello ' + firstname + ' ' + lastname); } if (language === 'es') { console.log('Hola ' + firstname + ' ' + lastname); } } } var greetEnglish = makeGreeting('en'); var greetSpanish = makeGreeting('es'); greetEnglish('Syed', 'Pasha'); greetSpanish('Syed', 'Pasha');
-
Callback Function:
A function which is given to another function, to be run when the other function is finished. So the function you call (invoke), 'calls back' by the calling the function you gave it when it finishes.
// Example of first-class function and closure function sayHiLater() { var greeting = 'Hi!'; setTimeout(function() { console.log(greeting); }, 3000); } sayHiLater();
-
All functions in javascript has access to the special methods such as
call,applyandbind. -
Bind:
Bind method return a new copy of the function. Reference of
thisobject is passed as parameter to the bind method. It does not execute the function.var person = { firstName: 'Syed', lastName: 'Pasha', getFullName: function() { var fullName = this.firstName + ' ' + this.lastName; return fullName; } } var logName = function(lang1, lang2) { console.log('Logged: ' + this.getFullName()); console.log('Arguments: ', lang1, lang2); } logName(); // This will throw an error, as undefined is not a function var logPersonName = logName.bind(person); // Here this will point to person object logPersonName('en');
-
Call:
Call method works similar to the function call, except it let us control the
thisreference of that function. Call method actually executes the function.var person = { firstName: 'Syed', lastName: 'Pasha', getFullName: function() { var fullName = this.firstName + ' ' + this.lastName; return fullName; } } var logName = function(lang1, lang2) { console.log('Logged: ' + this.getFullName()); console.log('Arguments: ', lang1, lang2); } logName.call(person); // Here function is executed with 'this' reference of 'person' object logName.call(person, 'en', 'es'); // argument can also be passed
-
Apply:
Its very similar to
callmethod, except the arguments are passed inside an array.var person = { firstName: 'Syed', lastName: 'Pasha', getFullName: function() { var fullName = this.firstName + ' ' + this.lastName; return fullName; } } var logName = function(lang1, lang2) { console.log('Logged: ' + this.getFullName()); console.log('Arguments: ', lang1, lang2); } logName.apply(person, ['en', 'es']); // argument has to be passed inside an array // Example 2: // Function borrowing: borrowing methods from other objects var person2 = { firstName: 'Afroz', lastName: 'Pasha' } person.getFullName.apply(person2);
-
Function Currying:
Creating a copy of a function but with some preset/default parameters. Its very useful in mathematical situation.
// Function Currying function multiply(a, b) { return a * b; } var multipleByTwo = multiply.bind(this, 2); // Here the first parameter is always set to 2 multipleByTwo(4); // Here 4 will act as second parameter
-
Functional Programming:
Using first-class functions to segment the code.
// Example of Function programming // Example 1 function mapForEach(arr, fn) { var newArr = []; for (var i = 0; i < arr.length; i++) { newArr.push( fn(arr[i]) ) } return newArr; } var arr1 = [1, 2, 3]; console.log(arr1); var arr2 = mapForEach(arr1, function(item) { return item * 2; }); console.log(arr2); // Example 2 var checkPastLimit = function(limiter, item) { return item > limiter; } var arr3 = mapForEach(arr1, checkPastLimit.bind(this, 1)); console.log(arr3); // Example 3 var checkPastLimitSimplified = function(limiter) { return function(limiter, item) { return item > limiter; }.bind(this, limiter) } var arr4 = mapForEach(arr1, checkPastLimitSimplified(2)); console.log(arr4); // Example 4 // Using underscore.js library var arr5 = _.map(arr1, function (item) { return item * 3; }) console.log(arr5); var arr6 = _.filter([2,3,4,5,6,7], function(item) { return item % 2 === 0; }); console.log(arr6);
-
Inheritance:
One object gets access to the properties and methods of another object. Javascript uses prototypal inheritance.
-
Prototype:
- Each object has its own prototype called proto, which is also a object.
- Object can share the prototype of other object.
- If any property is not found in the given object, then it will look up the prototype chain for that property in proto object.
var person = { firstName: 'Default', lastName: 'Default', getFullName: function() { var fullName = this.firstName + ' ' + this.lastName; return fullName; } } var syed = { firstName: 'Syed', lastName: 'Pasha' } // don't do this EVER! for demo purposes only! syed.__proto__ = person; console.log(syed.getFullName()); // output: Syed Pasha console.log(syed.firstName); // output: Syed var afroz = { firstName: 'Afroz' } afroz.__proto__ = person; console.log(afroz.getFullName()); // output: Afroz Default console.log(afroz.firstName); // output: Afroz
-
A prototype of a prototype is an object.
-
A base object is a bottom of prototype chain.
-
A base object doesn't have a prototype.
var a = {}; var b = function() {}; var c = []; a.__proto__ ; // This will return a 'base object' - {} // This will have properties and methods of object b.__proto__ ; // This will return an 'empty function object' - function Empty() {} // This will be the prototype of all the function in javascript // This will have properties and methods of function c.__proto__ ; // This will return an empty array // This will have properties and methods of array
-
Reflection:
An object can look at itself, listing and changing its properties and methods.
var person = { firstName: 'Default', lastName: 'Default', getFullName: function() { var fullName = this.firstName + ' ' + this.lastName; return fullName; } } var syed = { firstName: 'Syed', lastName: 'Pasha' } // don't do this EVER! for demo purposes only! syed.__proto__ = person; // Reflection for (var prop in syed) { console.log(prop + ': ' + syed[prop]); } for (var prop in syed) { if (syed.hasOwnProperty(prop)) { console.log(prop + ': ' + syed[prop]); } } // Extend // Using underscore.js var b = { address: '111 Main St.' getFormalFullName: function() { return this.lastName + ', ' + this.firstName } } var c = { getFirstName: function() { return firstName; } } _.extend(syed, b, c); console.log(syed);
-
Function constructor:
A normal function that is used to construct objects. The
thisvariable points a new empty object, and that object is returned from the function automatically.function Person() { this.firstName = 'Syed'; this.lastName = 'Pasha'; } // Another way of creating object in javascript var syed = new Person(); // Here 'new' is an operator // Here 'new' operator will create empty object and then add/call the Person function, with the 'this' variable point to empty object console.log(syed); // --------------------------- function Person(firstName,lastName) { console.log(this); this.firstName = firstName; this.lastName = lastName; } var syed = new Person('Syed', 'Pasha'); console.log(syed); var afroz = new Person('Afroz', 'Pasha'); console.log(afroz);
-
All Functions in javascript has some properties such as:
- Name
- Code
- prototype: Its used only by the
newoperator. its not the prototype of the function. Its a prototype of any object created using function contructor.
-
Any object created with function constructor, can be added with new features using prototype property of function constructor.
-
Methods created using prototype can be resued in all the object without creating a new memory space for that function/method.
function Person(firstName,lastName) { console.log(this); this.firstName = firstName; this.lastName = lastName; console.log('This function is invoked.'); } Person.prototype.getFullName = function () { return this.firstName + ' ' + this.lastName; } var syed = new Person('Syed', 'Pasha'); console.log(syed); var afroz = new Person('Afroz', 'Pasha'); console.log(afroz); Person.prototype.getFormalFullName = function () { return this.lastName + ', ' + this.firstName; } console.log(syed.getFormalFullName());
-
For prototype to work, we should define a function using
newkeyword. And the name of that function (function constructor) should be starting with Capital letter. -
Built-in function constructor:
// Here a will have property of number // This will create object var a = new Number('3'); console.log(a); // Number {3} // Here b will have property of string var b = new String('Syed'); console.log(b); // String {"Syed"} // We can add new feature using prototype String.prototype.isLengthGreaterThan = function(limit) { return this.length > limit; } console.log("Syed".isLengthGreaterThan(3)); // -------------------------------- var a = 3; // This one is primitive value var b = new Number(3); // This one will have object created with function constructor // This type of defining a variable should be avoided a == b // true a === b // false
-
Its better not to used built-in function constructors, instead use actual primitive values.
-
For iteration an array, don't use
for...ininstead usefor(var i = 0....).Array.propotype.myCustomFeature = 'cool'; var arr = ['a', 'b', 'c']; for (var prop in arr) { console.log(prop + ': ' + arr[prop]); }
-
Pure prototypal inheritance:
Object.create()creates an empty object with its prototype pointing to what ever that is passed into theObject.create().
var person = { firstName: 'Default', lastName: 'Default', greet: function() { return 'Hi ' + this.firstName; } } var syed = Object.create(person); console.log(syed); // returns Empty object, but prototype will have properties and methods of person object. syed.firstName = 'Syed'; syed.lastName = 'Pasha'; console.log(syed);
-
Polyfill:
code that adds a feature which the engine may lack.
-
ES6 and Classes:
// Another way of creating an object // Here 'extends' keyword sets the prototype class InformalPerson extends Person { constructor (firstName, lastName) { super(firstName, lastName); // This will call the constructor of object which is the prototype } greet() { return 'Yo ' + firstName; } }
-
Syntactic Sugar: A different way to type something that doesn't change how it works under the hood.
-
typeof and instanceof:
-
typeofis an operator that returns a string with the type of whatever you pass. -
The
typeofoperator checks if a value belongs to one of the six basic types:number,string,boolean,object,functionorundefined. -
instanceofis much more intelligent: it works on the level of prototypes. In particular, it tests to see if the right operand appears anywhere in the prototype chain of the left.
var a = 3; console.log(typeof a); // number var b = "Hello"; console.log(typeof b); // string var c = {}; console.log(typeof c); // object var d = []; console.log(typeof d); // object // Better approach console.log(Object.prototype.toString.call(d)); // [object Array] function Person(name) { this.name = name; } var e = new Person('Syed'); console.log(typeof e); // object console.log(e instanceof Person); // true console.log(typeof undefined); // undefined console.log(typeof null); // object var f = function() { }; console.log(typeof f); // function
-
-
Strict Mode:
It tell the javascript engine to implement some strict rules while parsing the code. Using
'use strict'in the code enables the strict mode. -
Method Chaining:
Calling one method after another, and each method affects the parent object. So
obj.method1().method2(), where both methods end up with athisvariable pointing toobj. -
Transpile:
Convert the syntax of one programming language, to another.
