1.Property Access :
what is an object ?
An object is a data structure.
we have key value pairs.we store our data in there.
And that data we store at those property names can be any type.
Accessing properties on an Object :
There are two ways to access properties on an object
1.Dot Notation
2.Bracket Notation/ Square bracket Notation
Note : Always use Dot Notation.But if you're dealing with invalid identifier
or variables,use the Bracket notation.
Dot Notation :
Use can Assign and access properties on an object using Dot Notation
ex : assignment with dot
var box={};
box.material ="cardboard";
var box = {"material":"cardboard"};
ex: access with dot
var box={};
box.material ="cardboard";
var cb = box.material;
console.log(cb); // cardboard
Brackets :
ex: var box ={};
box["material"] = "cardboard";
console.log(box.material); // cardboard
console.log(box["material"]); // cardboard
ex : variables
var box ={};
box["material"] ="cardboard";
var key = "material";
console.log(box[key]); // "cardboard"
ex: expressions
var box ={};
box["material"]="cardboard";
var func = function(){
return "material";
}
console.log(box[ func() ]); // "cardboard"
ex :
var box ={};
box['material'] ="cardboard";
var key ='material';
console.log(box['key']); // undefined
console.log(box.key); // undefined
console.log(box[key]); // "cardboard"
Note : if property doesn't exist on object , so it returns undefined.
Dot notation :
1.Property identifies can only be alphanumeric (_ and $).
2.Property identifiers cannot start with number
3.Property identifiers cannot contain variables.
ex: obj.prop_1, obj.prop$
Bracket Notation :
1.Property identifiers have to be a string or a variable that references a string.
2.It is okay to use variables,spaces and strings that start with numbers.
ex: obj["1prop"],obj{"prop Name"]
summary :
1.Dot notation is faster to write and clearer to read.
2.Square bracket notation allows access to properties containing special characters and selection of properties using variables.
3.Bracket notation expects an expression which evaluates to a string.
4.The dot notation only works with property names which are valid identifier name.
Brackets : quotes('') required for strings,weired characters.
quotes('') not required for variables,numbers and expressions.
Storing Data and Object-literal Notation :
we can store any data in our object.
ex:
var box = {};
box["material"]="cardboard";
box["size"] = {
"height" : 2,
"width" : 80
};
box.area= function(){
return box.size.height * box.size.width;
};
or
box['area'] = function(){
return box.size.height * box.size.width;
};
Access function :
ex :
box["area"]();
var func = 'area';
box[func]();
Note :
1.Objects created using object literals are singletons.
This means when a change is made to the object,it affects that object across the entire script.
2.Object defined with the function constructor let us have multiple instances of that object.
This means change made to one instance, will not affect other instances.
Object literal Notation
ex :
var box = {
material: "cardboard",
height : 2,
width : 80,
area : function(){
return this.height * this.width;
}
};
what are the different ways you can add properties and values to objects?
--> dot notation and bracket notation.
which of these methods would you use if you wanted to add a property to an object that had a weired symbol ('&')?
--> must use bracket notation
what about if the property is a variable, how does that change the syntax ?
--> must use bracket notation, no quotes
Object Iteration :
1. for..in loop
ex :
var box = {
material: "cardboard",
height : 2,
width : 80
};
for (let key in box){
console.log(key, box[key]); // prints key and value
}
2.with ES6 for..of using Object.entries
ex :
var box = {
material: "cardboard",
height : 2,
width : 80
};
for (let [key,value] of object.entries(box)){
console.log(key,value); // prints key and value
}
Note :
The keys,values and entries are 3 common lists to extract from a javascript objects.
1. The keys of an object is the list of property names.
2. The values of an object is the list of property values.
3. The entries of an object is the list of pairs of property names and corresponding values.
1.Object.keys() returns keys
2.Object.values() returns value
3.Object.entries() returns entries
or
1.The keys are returned by Object.keys(object)
2.The values are returned by Object.values(object)
3.The entries are returned by Object.entries(object)
Arrays :
==========
Arrays are a special type of objects, with numbered indexes.
Array is an object which is used to store a collection of values or items in a single variable.
Arrays allow us to store values without needing to assign keys.
ex :
let box = [];
box[0] = true;
box[1] = 'meow';
box.push({'hello':'goodbye'});
console.log(box[0]); // true;
console.log(box[1]); // 'meow'
console.log(box.pop()); // {'hello':'goodbye'}
Note : pop() method remove an item from the end of an array.
console.log(box); // [true,'meow'];
Note : push() method append items to the end of an array.
you can use push() method to append more than one item/value to an array in a single call.
ex:
// initialize array
let arr = ["Hi", "Hello", "Bonjour", "Hola"];
// append multiple values to the array
arr.push("Salut", "Hey");
ex : var box=[];
box['size'] =9;
box['0'] = 'meow';
console.log(box) ; // ["meow", size: 9]
console.log(box['size']) // 9
console.log(box[0]); // 'meow'
Note : An array is an object that means you can add properties to it.
ex : var box=[];
box['size']=9;
box['0']='meow';
console.log(box) // ["meow", size: 9]
box.size; // 9
box[0]; // 'meow'
Iteration :
ex :
var box=[];
box['size'] =9;
box['0']='meow';
for(let key in box){
console.log(key); // 0,size
}
for(let key in box){
console.log(box[key]); // meow,9
}
Native properties :
ex : var box =[];
box['0']='meow';
box[3]={'babyBox':true};
box['length']; // 4
Note : The array length property is keeping track of the numerical indices,
every time you add something to it.
ex :
var box =[];
box['0'] = 'meow';
box[1] = {'babyBox': true};
box[length]; // undefined
The length variable is not defined/declared .
ex : var box =[];
box['0'] = 'meow';
box[1] = {'babyBox': true};
box[box.length-1]; // {babyBox: true}
How to add values & indices to arrays ?
1.bracket notation
2.bracket notation with variable
3.dot notation
4.native methods
5.length property
How to access values & indices to arrays ?
1.bracket notation
2.bracket notation with variable
3.dot notation
4.native methods
5.length property
Create an array
ex : let noiseArray =['purr'];
Add item to the beginning of an Array
ex : noiseArray.unshift('hiss');
Add item to the end of an array.
ex : noiseArray.push('meow');
Using bracket notation add item to an array.
ex : noiseArray[3] ='growl';
Inspect an Array :
1. length of an array.
ex : let totalitems = noiseArray.length;
index starts from 0 so the last index is 1 less than the length.
Nest the array in the object
ex : animal.noises = noiseArray;
console.log(animal);
What are the different ways you can add properties and values to arrays?
use bracket notation or native array methods
Come up with two ways you can add an element to the end of an array, without knowing the exact length of the array.
use arr.push() or arr[arr.length]
Functions :
==========
parameters are variables listed as a part of the function definition.
Arguments are values passed to the function when it is invoked.
The arguments object is an array-like construct which can be used to access arguments
passed to the function even if a matching parameter isn't explicitly defined.
The "argument object" is an array-like object that stores all the parameters passed to a function.
even if the function declaration doesn't specify any parameters.
function argumentVar(parameter1, parameter2, parameter3){
console.log(arguments.length); // Logs the number of arguments passed.
console.log(arguments[3]); // Logs the 4th argument. Follows array indexing notations.
}
argumentVar(1,2,3,4,5);
// Log would be as follows
// 5
// 4
ex :
function addAlltheNumbers(){
var argsArray = Array.prototype.slice.call(arguments);
return argsArray.reduce( (acc,cur) => acc + cur);
}
addAlltheNumbers(1543,3298,1729,1449,1435); // 10000
Constructor :
function AnimalMaker(name){
return {
speak : function (){
console.log("my name is ", name);
}
};
}
var myAnimal = AnimalMaker('tiger');
myAnimal.speak; // f(){ console.log("my name is ",name);}
myAnimal.speak(); // my name is tiger
ex :
function AnimalMaker(name){
return {
speak : function (){
console.log("my name is ", name);
}
};
}
var animalNames =['Sheep','Liger','Big Bird'];
var farm[];
for(let i =0; i < animalNames.length;i++){
farm.push(AnimalMaker(animalNames[i]));
}
for (let j=0; j<farm.length;j++){
farm[j].speak();
}
ex :
function AnimalTestUser(username){
let args = arguments.length;
let otherArgs = [];
if(args>1){
for( let i=1;i<args;i++){
otherArgs.push(arguments[i]);
}
}
return {
username:username,
otherArgs:otherArgs
};
}
without arguments :
let myAnimal = AnimalTestUser('cow');
console.log( myAnimal.username); // cow
with arguments :
var testSheep = AnimalTestUser('CottonBall', {'loves dancing': true}, [1,2,3] );
console.log(testSheep); ////{ username: 'CottonBall', otherArgs: [ {'loves dancing': true}, [1,2,3] ] }
ex:
function AnimalCreator(username,species,tagline,noises){
var animal = {
username:username,
species : species,
tagline : tagline,
noises : noises,
friends : []
};
return animal;
}
let sheep = AnimalCreator('Cloud','sheep','you can count on me!',['baahhh','arrgg','chewchewchew']);
console.log(sheep);
// { username: 'Cloud',
// species: 'sheep',
// tagline: 'You can count on me!',
// noises: ['baahhh', 'arrgg', 'chewchewchew'],
// friends: []
// }
function addFriend(animal,friend){
animal.friends.push(friend.username);
}
let cow = AnimalCreator('Moo','cow','got milk?',['moo','moooo','mooo']);
let llama= AnimalCreator('Zeny','llma','llll',['sdf','sdfsf']);
addFriend(sheep,cow);
addFriend(sheep,llama);
let myFarm = [sheep,cow,llama];
addFriend(cow,sheep);
addFriend(llama,cow);
function addMatchesArray(farm){
for(let animal in farm){
farm[animal].matches=[];
}
}
addMatchesArray(myFarm);
console.log(myFarm[0]);
function giveMatches(farm){
for(let animal in farm){
farm[animal].matches.push(farm[animal].friends[0]);
}
}
giveMatches(myFarm);
console.log(myFarm[0]);
Nesting :
===========
ex: var box = {};
box.innerBox={};
( or)
var box = {"innerBox":{}};
ex:
var box ={};
box['innerBox']={};
ex :
var box ={};
box['innerBox'] ={};
box['innerBox']['full']=true;
(or)
var box = { 'innerBox':{full:true}};
Scope :
=========
Scope is created dynamically whenever we call the function.
A function has access to its own local scope variables.
Different Types of Scopes :
1.Global Scope
2.Function Scope(local scope)
3.Module Scope
4.Block Scope
5.Lexical Scope
Scope is the region of the codebase over which an identifier is valid.
1.Global Context :
Variables declared directly in the global context, in which case they are added as properties on the global context.
Global Variables are available for the lifetime of the application.
There is only one Global scope throughout a javascript document.
A variable is in the Global scope if it's defined outside of a function.
Note : You can also access and alter any variable declared in a global scope from any other scope.
ex :
function f1(){
console.log(' I am global function');
}
f1(); // I am global function
window.f1(); // I am global function
ex:
var x ='global !';
function encapsulate(){
z =' global here, too !';
window.y='also global';
}
2.Function Scope :
Variables defined in a function are visible everywhere within the function,
but are not visible outside of the function.
Variables declared within a function are in the local scope.
Local scope is also called function scope because local scope is created by functions in Javascript.
ex:
var func = function(){
var local = true;
}
Note :
1.Variables declared with 'var' have only function scope.
2.Variables declared with 'var' hoisted to the top of their scope.
3.Block Scope :
A block is a set of opening and closing curly brackets.
In ES6, 'let' and 'const' keywaords allow developers to declare variables in the block scope,
which means those varaiables exist only within the corresponding block.
A block scope is the area within 'If','switch', conditions or 'for' and 'while' loops.
ex : function foo(){
if(true){
var fruit1 ='apple'; // exist in function scope
let fruit2 ='banana'; // exist in block scope
const fruit3='strawberry'; // exist in block scope
}
console.log(fruit1);
console.log(fruit2);
console.log(fruit3);
}
// Result :
// apple
// error: fruit2 is not defined
// error: fruit3 is not defined
Block scope is everything inside a set of braces.
ex : { a block scope here }
Note : A Block scope is sometimes the same as a function scope.
so, at the top of a function's code, a block scope will be the same as a function scope.
ex :
function test(x){
// this is both a block scope and a function scope
let y = 5;
if(x){
// this is a smaller block scope that is not the same as the function scope
let z=1;
}
}
Note :
'var' is not limited to the curly brackets.
'var' is a function scope.
Function scope is within the function.
4.Lexical scope :
Lexical scope means the children scope have the
access to the variables defined in the parent scope.
The children functions are lexically bound to the execution context of their parents.
This lexical scope is heavily used in closures in javascript.
ex :
function outerScope(){
var name ='Juan';
function innerScope(){
console.log(name ) ; // Juan
}
return innerScope;
}
const inner = outerScope();
inner();
5.Module scope
With the introduction of modules in ES6, it was important for variables in a module to
not directly affect variables in other modules.
Modules create their own scope which encapsulate all variables created with
var,let or const similar to the function scope.
A module is just a file which can be imported from other modules (or files) through the help of directives
like 'export' and 'import'.
Parent vs Child scope :
ex :
function blender ( fruit){
var b= fruit;
var y = 'yogurt';
function bs(){
var x='asdf';
console.log( b + ' and ' + y + ' Makes '+b+' swirl');
}
bs();
}
blender('blueberry'); // blueberry and yogurt Makes blueberry swirl
Note : child scope can access variables from parent scope. but parent scope cannot access from child scope
Precedence :
The local variable always get priority over the global variables with same name.
if you declare a local variable and a global variable with the same name,
the local variable will take precedence when you use it inside a function.
This type of behavior is called shadowing(variable shadowing).
ex :
var g ='global';
function go(){
var l ='local';
var g ='in here !';
console.log( g + " inside go");
}
go(); // in here inside go
console.log( g + " outside go'); // global outside go
Note :
The local variables always get priority over the global variables with same name.
Summary :
1. A function has access to its own local scope variables
ex : var ACTUAL;
var fn = function(){
var name='inner';
ACTUAL=name;
console.log(ACTUAL);
}
fn(); // inner
console.log(ACTUAL); // inner
2.Inputs to a function are treated as local scope variables.
ex :
var ACTUAL;
var fn=function(name){
ACTUAL=name;
console.log('local scope',ACTUAL);
}
fn('inner');
console.log('outer scope',ACTUAL);
Result :
// local scope inner
// outer scope inner
3.A function has access to the variables contained within the same scope that function was created in.
ex : var ACTUAL;
var name ='outer';
var fn = function(){
ACTUAL=name;
}
fn();
console.log(ACTUAL); // outer
4. A function's local scope varaiables are not available anywhere outside that function.
ex : var firstFn = function(){
var localToFirstFn = 'inner';
}
firstFn();
console.log(localToFirstFn); // Uncaught ReferenceError: localToFirstFn is not defined
5.A function's local scope variables are not anywhere outside that function, regardless of the context it's called in.
ex:
var ACTUAL;
var firstFn=function(){
var localToFirstFn = 'first';
secondFn();
}
var secondFn = function(){
ACTUAL = localToFirstFn;
}
secondFn(); // Uncaught ReferenceError: localToFirstFn is not defined
Note : since secondFn does not have access to the localToFirstFn variable.
firstFn(); // Uncaught ReferenceError: localToFirstFn is not defined
Note : calling the firstFn(which in turn calls the secondFn) should also throw,
since it is calling context of secondFn has no influence over its scope access rules.
6. If an inner and outer variable share the same name,and the name is referenced in the inner scope,
the inner scope variable masks the variable from the outer scope with the same name.
This renders the outer scope variables inaccessible from anywhere within the inner function block.
ex : var ACTUAL;
var sameName='outer';
var fn = function(){
var sameName='inner';
ACTUAL=sameName;
};
fn();
console.log(ACTUAL); // inner
7. if an inner and an outer variable share the same name,and the name is referenced
in the outer scope,the outer value binding will be used.
ex :
var ACTUAL;
var sameName='outer';
var fn = function (){
var sameName ='inner';
}
fn();
ACTUAL=sameName;
console.log(ACTUAL); // outer
8.A new variable scope is created for every call to a function,
as exemplified with a counter.
ex : var ACTUAL;
var fn = function(){
var innerCounter = innerCounter || 10;
innerCounter = innerCounter + 1;
ACTUAL = innerCounter;
}
fn();
console.log(ACTUAL); // 11
fn();
console.log(ACTUAL); // 11
9.A new variable scope is created for each call to a function, as
exemplified with uninitialized string variables.
ex : var ACTUAL;
var fn = function(){
var localVariable;
if(localVariable === undefined){
ACTUAL='alpha';
} else if (localVariable === 'initialized'){
ACTUAL ='omega';
}
localVariable='initialized';
}
fn();
console.log(ACTUAL); // alpha
fn();
console.log(ACTUAL); // alpha
10. An inner function can access both its local scope variables and variables in its containing scope,
provided the variables have different names;
ex : var outerName ='outer';
var fn =function(){
var innerName ='inner';
ACTUAL = innerName + outerName;
}
fn();
console.log(ACTUAL); //innerouter
11. Between calls to an inner function, that inner function retains access to a variable in an outer scope.
Modifying those variables has a lasting effect between calls to the inner function.
ex : var ACTUAL;
var outerCounter = 10;
var fn = function () {
outerCounter = outerCounter+1;
ACTUAL=outerCounter;
}
fn();
console.log(ACTUAL); // 11
fn();
console.log(ACTUAL); // 12
12.The rule about retaining access to variables from an outer scope still applies,
even after the outer function call ( that created the outer scope) has returned.
ex : var ACTUAL;
var outerFn = function(){
var counterInOuterScope = 10;
var innerIncrementingFn = function(){
counterInOuterScope = counterInOuterScope + 1;
ACTUAL=counterInOuterScope;
}
innerIncrementingFn();
console.log(ACTUAL); // 11
innerIncrementingFn();
console.log(ACTUAL); // 12
window.retainedInnerFn = innerIncrementingFn;
};
console.log(window.retainedInnerFn); // undefined
outerFn();
console.log(window.retainedInnerFn); // function
window.retainedInnerFn();
console.log(ACTUAL); // 13
Closure :
===========
A closure happens when you return a function from inside of the function,
and that inner function retains access to the scope.
The closure has three scope chains :
1.it has access to its own scope.
2.it has access to the outer function scope.
3.it has access to the global scope.
Note : The inner function will have access to the variables in the outer function scope, even after the outer function has returned.
ex :
var closureAlert = function(){
var x = " Help! I'm a variable stuck in a closure!";
var alerter = function (){
console.log(x);
}
setTimeout(alerter,1000);
console.log('will still run right after');
};
closureAlert();
Result :
will still run right after
Help! I'm a variable stuck in a closure!
ex :
var closureAlert = function (){
var x = 0;
var alerter = function(){
console.log(++x);
};
return alerter;
};
var funcStorer = closureAlert();
var funcStorer2 = closureAlert();
funcStorer(); // 1
funcStorer(); // 2
funcStorer2(); // 1
ex :
var add = function(num){
var num1=num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var add5 = add(5);
add5(2); // 7
add5(3); // 8
Closure Object :
ex :
function counter(){
var n =0;
return {
count : function() { return ++n;},
reset : function() { n =0; }
};
};
var myCounter = counter();
myCounter.count(); // 1
myCounter.count(); // 2
myCounter.count(); // 3
Callbacks :
============
1. Module pattern :
Module pattern is a commonly used design pattern which is used to wrap a set of variables
and functions together in a single scope.
Module pattern is used to define objects and specify the variables and the functions that can be accessed
from outside the scope of the function.
we expose certain properties and function as public and can also restrict the scope of properties and functions within the object itself,making them private.
This means that those variables cannot be accessed outside the scope of the function.we can achieve data hiding an abstraction using this pattern in the javascript.
Benefits of module pattern :
1.Maintainability :
2.Reusability
Higher-Order Functions :
1.takes a function as an input (argument)
ex : element.addEventListener("click",function(){
console.log("element clicked!");
});
2.Returns a function as an output
ex : var add = function(num){
var num1=num;
return addToNum1 = function(num2){
return num1 + num2;
}
};
Callbacks :
we can pass functions as parameters to other functions and call them inside the outer functions.
ex : var ifElse = function(condition, isTrue,isFalse){
if(condition){
isTrue;
}else{
isFalse;
}
};
ifElse(true,function(){ console.log(true);},
function(){ console.lof(false);}
);
ex :
const message = function(){
console.log("this message is shown after 3 seconds");
}
setTimeout(message,3000);
Note : The message function is a callback function.
ex : Anonymous function
setTimeout(function(){
console.log(" This message is shown after 3 seconds");
},3000);
The callback function here has no name and a function definition without a name in javascript
is called as an "anonymous function".
ex : callback as an Arrow function
setTimeout(()=>{
console.log("this message is shown after 3 seconds");
},3000);
you can write the callback function as an ES6 arrow function.
ex : Events
<button id="callback-btn">Click here</button>
document.queryselector("#callback-btn")
.addEventListener("click", function() {
console.log("User has clicked on the button!");
});
callback functions are used for event declarations in javascript.