//-------------------------------------------PROTOTYPES-----------------------------------------------
// Javascript is built on prototypes and classes are syntactic sugar on prototypes.
// Whenever we create an object then Javascript engine assign some hidden properties to our object. We can access these hidden properties just like we access those properties that we defined ourself. 
// Not just objects, functions and arrays are also assigned some hidden properties that we can access by using their names.
// Javascript engine puts these hidden properties into an object and attaches it to our original object and that is how we get access to those hidden properties.
// So if we want to access that hidden object we can use __proto__ .
const arr = ["Deep", "SDE", "22"]
console.log(arr.__proto__) //accessing the hidden object attached to our array by js engine. Same is the case with function and objects.
console.log(arr.__proto__.concat) // now here by using __proto__ object we can access all the properties that are there in the __proto__ object.

//Every Object is Javascript has a prototype.
//As arr.__proto__ is itself an object so it also has a prototype attached to it
console.log(arr.__proto__.__proto__)
// arr.__proto__ is similar to Array.prototype and arr.__proto__.__proto__ is similar to Object.prototype.
// This is an prototype chain, where array has a prototype which is an array prototype and that array prototype has an prototype which is an Object prototype and that Object's prototype is null.

function fun() {
  //
}
//Similarly fun.__proto__ is similar to Function.prototype and fun.__proto__.__proto__ is similar to Object.prototype and that object prototype's prototype is null.
// So this proves that whatever we make, an array or function or anything. It's prototype comes down to be an object so this proved that everything in Javascript is an object.

const obj = {
  name: 'Deep',
  age: 21,
  city: 'UP',
  getIntro: function() {
    console.log(`${this.name} from ${this.city}`)
  }
}
const obj2 = {
  name: 'Deepanshu'
}
obj2.__proto__ = obj //here obj2 is inheriting properties from __proto__ which is pointing towards the obj.
console.log(obj2.name) // here we will get 'Deepanshu' as js engine will look into obj2 first.
console.log(obj2.city) //here we will get 'UP' as js engine will look into obj2 and when it does not find city key then it will inherit the city from it's prototype which is pointing to obj.
obj2.getIntro() // this will print Deepanshu from UP as in this case our 'this' keyword will be pointing to name of deepanshu and city will come from obj as we do not have any city in obj2.

//We can also create objects that does not have any prototype by using a function Object.create()
const newObj = Object.create(null) // in Object.create() function we pass anything that we want our Object's prototype to be.
console.log(newObj) // so here newObj will not have any prototype.
console.log(Object.getPrototypeOf(newObj)) //this will be null
const newObj1 = {}
console.log(newObj1) //newObj1 will have a prototype assigned by js engine by default.
// We can use this create() function to set prototype of any object of our own choice
const newObj2 = Object.create({abc: 123})
console.log(Object.getPrototypeOf(newObj2)) //this will print {abc:123}
console.log(newObj2.abc) //this will print 123 as newObj2 inherited all the properties of its prototype
// When we try to access a property of any object then our js engine search that property from top to bottom of it's prototype chain if not found anywere it will print null.
//Every function in Javascript has a property 'prototype' with it assigned by Javascript engine and it points to an object
function Pokemon(name, type) //this is a contructor function
{
  // this = {} //this is built behind the scenes
  this.name = name
  this.type = type
  // return this  //this happens behind the scenes as a this object is built and we manipulate it and use it by using our code and then js internally return 'this'
}

const pikachu = new Pokemon('pikachu', 'electric')
console.log(pikachu)

Pokemon.prototype.speak = function () { //here we are assigning a speak function to the Pokemon.prototype .Now it hs a speak property and a constructor function.
  console.log('pika pika')
}
console.log(Pokemon.prototype.speak)
Pokemon.prototype.speak()
console.log(Pokemon.__proto__)
console.log(Object.getPrototypeOf(Pokemon)) // this function return __proto__ of the object we pass in it.
//Now whenever we create object using New operator what Javascript does is it assign __proto__ to it which links to the Pokemon.prototype. So pikachu.__proto__ === Pokemon.prototype(Pokemon.prototype is the prototype of the constructor function)
console.log(pikachu.__proto__ === Pokemon.prototype)
// So __proto__ helps to link with prototypes in prototype chain.





//-------------------------------------------CLASS-BASICS------------------------------------------------
//We can do all the things that prototype allows us to do with class with much better code.
class Human { // we can create a class using the class keyword.
  constructor(name, age) { // a constructor function which is built using the constructor keyword and it will be used to make instances of this Human class.
    this.name = name
    this.age = age
  }
  printName() { //this is similar to Human.prototype.printName()
    console.log(this.name) //here the scope of this will be the object which is calling it.
  }
  //We can also define static property by using the keyword 'static
  static sayHello() { //This function is added to the class and will not be accessible by its instances.
    console.log('Hello')
  }
  static badName = 'knkkn'
  get name1() { //getter function
    return this.name
  }
  set name1(value) { //setter function 
    this.name = value
  }
  
}

Human.sayHi = function (){ //these are static properties of class and will not be accessible by it's instances.
  console.log('Hi')
}
Human.goodName = 'Deep1'
const hmn = new Human('Deep', 22)
hmn.name1 = '1111'//using the setter function
console.log(hmn.name1) //using the getter function of the class.
hmn.printName()
Human.sayHi()
console.log(Human.goodName)
console.log(hmn.goodName) // this will be undefined as goodName is static property of class and not of it's objects.
//We can also define static property by using the keyword 'static








//-------------------------------------------CLASS-INHERITENCE------------------------------------------------
class Animal {
  constructor(name) {
    this.name = name
  }
  speak () {
    console.log(`Hi my name is ${this.name}`)
  }
}
const animal1 = new Animal('bsr')
animal1.speak()
//Suppose we want this Animal class to get inherited to further classes we can use 'extend' keyword and all the derived class will have the properties of this Animal class

class Dog extends Animal { //Here we are kind of setting the Animal class as the prototype of our dog class
  constructor(name, owner) {
    super(name) //we call this super() to call the constructor of base class
    // this.name = name  // we dont need to do this as we are calling the constructor of our base class whcih will set the name of our animal
    this.owner = owner
  }
  speak() { //this will overwrite the speak function of animal class.
    console.log('Bark')
  }
}

const dog = new Dog('fluffy', 'Kylee')
console.log(dog)
dog.speak()

class Cat extends Animal {
  // constructor(name) { as our constructor is exactly the same as our base class then we dont need to rewrite it and js engine will use the base class's constructor
  //   super(name)
  // }
  speak() {
    console.log('Meow')
  }
}

const cat = new Cat('pri') 
console.log(cat)
cat.speak()





//--------------------------------------------PUBLIC-PRIVATE-AND-PROTECTED-PROPERTIES------------------------------------------------
// Public properties are accessible to the class itself, it's derived classes and all of the instances of that class or it's derived classes.
console.log(cat.name)//here the derived class(cat) is using the property name of its base class as name is by default public.
//Suppose we want a variable to not get accessed outside the class then we can use private and protecte property of inheritence.
//To make a property private in a class we use # before its name. By doing this it will not be available outside the class definition and even its instances(objects) won't be able to access it.

class PropertyTest {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  _proVar = 22 //we used _ to make it identify it as a protected variable.
  #gettingSalary = true //here by using # we made this varibale private and it will only be accessible inside the class only
  print1() {
    if(this.#gettingSalary === true) {
      console.log(this.#gettingSalary)
    }
  }
}

const ob = new PropertyTest('Deeo', 22)
ob.print1() // here we are trying to access the private variable by using it inside a publiv funciton while defining the class
console.log(ob.gettingSalary) //this will print undefined as gettingSalary is a private memeber of class PropertyTest
//Private variables are not available in derived classes and their instances.
//Here comes the concept of protected class. It is same as private class but the protected properties are available to the children or derived classes.
//As we do not have a way to make a Property protected we try to fake it by applying _before the name so that to identify it as a protected Property
class childTest extends PropertyTest {
 
}

const aa = new childTest('njn', 22)
console.log(aa._proVar) //here object of derived class is able to access the protected variable of its base class.




















 
by

Javascript Online Compiler

Write, Run & Share Javascript code online using OneCompiler's JS online compiler for free. It's one of the robust, feature-rich online compilers for Javascript language. Getting started with the OneCompiler's Javascript editor is easy and fast. The editor shows sample boilerplate code when you choose language as Javascript and start coding.

About Javascript

Javascript(JS) is a object-oriented programming language which adhere to ECMA Script Standards. Javascript is required to design the behaviour of the web pages.

Key Features

  • Open-source
  • Just-in-time compiled language
  • Embedded along with HTML and makes web pages alive
  • Originally named as LiveScript.
  • Executable in both browser and server which has Javascript engines like V8(chrome), SpiderMonkey(Firefox) etc.

Syntax help

STDIN Example

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', function(line){
    console.log("Hello, " + line);
});

variable declaration

KeywordDescriptionScope
varVar is used to declare variables(old way of declaring variables)Function or global scope
letlet is also used to declare variables(new way)Global or block Scope
constconst is used to declare const values. Once the value is assigned, it can not be modifiedGlobal or block Scope

Backtick Strings

Interpolation

let greetings = `Hello ${name}`

Multi line Strings

const msg = `
hello
world!
`

Arrays

An array is a collection of items or values.

Syntax:

let arrayName = [value1, value2,..etc];
// or
let arrayName = new Array("value1","value2",..etc);

Example:

let mobiles = ["iPhone", "Samsung", "Pixel"];

// accessing an array
console.log(mobiles[0]);

// changing an array element
mobiles[3] = "Nokia";

Arrow functions

Arrow Functions helps developers to write code in concise way, it’s introduced in ES6.
Arrow functions can be written in multiple ways. Below are couple of ways to use arrow function but it can be written in many other ways as well.

Syntax:

() => expression

Example:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const squaresOfEvenNumbers = numbers.filter(ele => ele % 2 == 0)
                                    .map(ele => ele ** 2);
console.log(squaresOfEvenNumbers);

De-structuring

Arrays

let [firstName, lastName] = ['Foo', 'Bar']

Objects

let {firstName, lastName} = {
  firstName: 'Foo',
  lastName: 'Bar'
}

rest(...) operator

 const {
    title,
    firstName,
    lastName,
    ...rest
  } = record;

Spread(...) operator

//Object spread
const post = {
  ...options,
  type: "new"
}
//array spread
const users = [
  ...adminUsers,
  ...normalUsers
]

Functions

function greetings({ name = 'Foo' } = {}) { //Defaulting name to Foo
  console.log(`Hello ${name}!`);
}
 
greet() // Hello Foo
greet({ name: 'Bar' }) // Hi Bar

Loops

1. If:

IF is used to execute a block of code based on a condition.

Syntax

if(condition){
    // code
}

2. If-Else:

Else part is used to execute the block of code when the condition fails.

Syntax

if(condition){
    // code
} else {
    // code
}

3. Switch:

Switch is used to replace nested If-Else statements.

Syntax

switch(condition){
    case 'value1' :
        //code
        [break;]
    case 'value2' :
        //code
        [break;]
    .......
    default :
        //code
        [break;]
}

4. For

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
//code  
} 

5. While

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while (condition) {  
  // code 
}  

6. Do-While

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {  
  // code 
} while (condition); 

Classes

ES6 introduced classes along with OOPS concepts in JS. Class is similar to a function which you can think like kind of template which will get called when ever you initialize class.

Syntax:

class className {
  constructor() { ... } //Mandatory Class method
  method1() { ... }
  method2() { ... }
  ...
}

Example:

class Mobile {
  constructor(model) {
    this.name = model;
  }
}

mbl = new Mobile("iPhone");