console.log(a); var a = 10; var b = 20; console.log(a); //the above code executes as below internally due to hoisting //variable hoisting var a, b; console.log(a); a = 10; b = 20; console.log(a); //function hoisting //below is not hoistied console.log(square(5)); var square = function (n) { return n * n; }; //the above code executes internally like this var square; console.log(square(5)); square = function (n) { return n * n; }; //however below is hoistied console.log(square(5)); function square(n) { return n * n; } var user = { name: "viknesh", print: function (prefix, end) { console.log(` Hi my name is ${prefix} ${this.name}. ${end}`); }, }; // user.print('Mr', 'bye') var test_user = { name: "test", print: function () { console.log(`Hi my name is ${this.name}`); }, }; // test_user.print() //user.print.apply(test_user, ['Mr', 'bye']) // user.print.call(test_user, 'Mr', 'bye') var print_later = user.print.bind(test_user, "Mr", "bye"); var test_print = user.print; console.log(test_print); print_later(); function User(name, age) { console.log(this); this.name = name; this.age = age; } User.prototype.print = function () { console.log(`Hi my name is ${this.name} and my age is ${this.age}`); }; User.prototype.country = "India"; var viknesh = new User("viknesh", 25); viknesh.print(); console.log(viknesh.country); console.log(User.prototype); function User2(name, age) { console.log(this); this.name = name; this.age = age; this.country = "India"; this.print = function () { console.log(`Hi my name is ${this.name} and my age is ${this.age}`); }; } var viknesh = new User2("viknesh", 24); viknesh.print(); //Inheritance function Student(name, age, standard, section) { User.call(this, name, age); // User(name, age) /* this.name = name; this.age = age */ this.standard = standard; this.section = section; } extend(User, Student); /* Student.prototype = Object.create(User.prototype) Student.prototype.constructor = Student */ Student.prototype.print = function () { console.log( `Hi my Info \n Name:${this.name} \n Age: ${this.age} \n Standard: ${this.standard} \n Section: ${this.section}` ); }; console.log(Student.prototype.constructor); var test_student = new Student("test", "15", "8th", "A"); test_student.print(); console.log(test_student.standard); //generic function to do inheritaslnce function extend(parent, child) { //shallow clone parent prototype to child child.prototype = Object.create(parent.prototype); //above code replaces constructor , so to correct it below code child.prototype.constructor = child; } //Scoping var z; console.log(z)( /* *The closure function has access to the scope in which it was created, not the scope in which it is executed. */ function autorun() { let x = 1; function log() { console.log(x); } function run(fn) { let x = 100; fn(); } run(log); //1 } )(); //Shallow clone // primitive types are pass by value, Object and Array are reference types // so use Object.assign to avoid references var x = { name: "viknesh" }; var y = Object.assign({}, x); console.log("x", x); y.name = "test"; console.log("x", x); //similar for array let a = [10, 20]; let b = a.concat(); console.log("a", a); b.push(30); console.log("a", a); //tricky part var a = { name: "viknesh", things: [10, 20] }; var b = Object.assign({}, a, { name: "test" }); console.log("b -> things", b.things); // [10, 20] b.things.push("test"); //reference b.things = a.things.concat(30); //wont reference console.log("b -> things", b.things); // [10, 20, test, 30] console.log("a -> things", a.things); // [10, 20, test] /* equality for null and undefined */ null == undefined; //true - Reason: type coercion null === undefined; //false /*****************closure**********************/ for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i); //3 3 3 }, 1000); } //To print the correct value //(1) use IIFT for (var i = 0; i < 3; i++) { setTimeout( (function (index) { return () => console.log(index); //1 2 3 })(i), 1000 ); } //(2) use let (why works ? bcoz let is block scoped) for (let i = 0; i < 3; i++) { setTimeout(function () { console.log(i); //0 1 2 }, 1000); } /**********************************************/ /***********************prototype chain***********************/ const machine = { motors: 4 }; const robot = { friendly: true }; const robby = {}; robot.__proto__ = machine; //Object.setPrototypeOf(robot, machine) robby.__proto__ = robot; console.log(robby); // {} //looks up in the chain console.log(robby.friendly); //true console.log(robby.motors); //4 //checks in prototype chain only if property is not available , wont override the existing property //Java like languages creates a copy of parent classes , while in JS it just delicates const bobby = { motots: 0, friendly: false }; bobby.__proto__ = robot; console.log(bobby.motors, bobby.friendly); // 0 false /**********************************************/ /*******************Prototype Chain - With Scope************* */ const machine = { motors: 4, speak: function () { console.log( `I have ${this.motors} motors and I am ${ this.friendly ? "friendly" : "un-friendly" }` ); }, }; const robot = { friendly: true, speak: function () { console.log(`Well, I am robot`); }, }; const robby = { motors: 0, friendly: false }; robot.__proto__ = machine; robby.__proto__ = robot; machine.speak(); robot.speak(); robby.speak(); /***************************************************************/ /*************************Implement new ***********************/ function Person(name) { this.name = name; } Person.prototype.speak = function () { console.log("Hello!! It's" + this.name + "here!!"); }; var thanos = new Person("Thanos"); //Implmentation above line function spawn(constructor, ...args) { //creates a objects let obj = {}; //sets the prototype Object.setPrototypeOf(obj, constructor.prototype); //executes the constructor with correct context return constructor.apply(obj, args); } var ironMan = spawn(Person, "Iron Man"); /***************************************************************/ /*******************Functional Programming**********************/ //1...Declarative const array = [1, 2, 3, 4, 5]; const sum = array.reduce((acc, val) => acc + val); //... //2...Closure const print = function (name) { return function (prefix) { console.log(`Hi, ${prefix} ${name}`); }; }; const printer = print("Bob"); printer("Mr"); //Hi, Mr Bob //... //3....Partial functions const partialApply = (fn, ...fixedArgs) => { return function (...remainingArgs) { return fn.apply(this, fixedArgs.concat(remainingArgs)); }; }; const add10 = partialApply(add, 10); add10(5); //... //4...Curring //add(1,2,3) const add = function (a) { return function (b) { return function (c) { return a * b * c; }; }; }; add(1)(2)(3); //... //5...Pure functions //Given a input returns a same out //Dont have side effects (does not modify anything outside the function) Math.random(); //not a pure function - returns a randon result var double = (x = x * x); //pure function //... //6...Composition //f(g(x)) //output of one fn is input for another //below not composed const toSlug = (input) => encodeURIComponent( input .split(" ") .map((str) => str.toLowerCase()) .join("-") ); toSlug("Foo Bar"); //foo-bar //composed , but not readable const toSlug = (input) => encodeURIComponent(join("-")(map(toLowerCase)(split(" ")(input)))); //composed and redable const toSlug = compose( encodeURIComponent, join("-"), map(toLowerCase), split(" ") ); //implementation of compose const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x); /************************************************************* */ class Person { constructor(name, age) { this.name = name; this.age = age; // this.greet = this.geet.bind(this) } greet() { console.log(`Hi i am ${this.name} and age is ${this.age}`); } } let viknesh = new Person("Viknesh", 28); let globalGreet = viknesh.greet; viknesh.greet(); globalGreet(); /*******************************************************************/ var person = { name: "viknesh", age: 27, greet: function () { console.log("Hello !", this.name); }, }; person.greet(); //Hello viknesh person.greetWithAge = function () { function getAge() { //this points to global return this.age; } console.log(`Hello ${viknesh}! your age is ${getAge()}`); }; person.greetWithAge(); //Hello viknesh! your age is undefined // setTimeout is a min time of execution, dont block the event loop setTimeout(() => { console.log("I will execute after 5 sec"); }, 5000); var start = new Date().getTime(); var end = start + 10000; while (start < end) { start = new Date().getTime(); } /* Reference http://es6-features.org/#Constants https://medium.com/dev-bits/a-perfect-guide-for-cracking-a-javascript-interview-a-developers-perspective-23a5c0fa4d0d https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance https://flaviocopes.com/javascript-event-loop/ https://codeburst.io/es6-destructuring-the-complete-guide-7f842d08b98f https://medium.freecodecamp.org/the-complete-javascript-handbook-f26b2c71719c */