├── .gitignore ├── README.md ├── advanced ├── 1. call-apply-bind-methods │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ └── example6.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ └── practice2.md │ └── README.md ├── 2. factory-pattern │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ └── example5.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ ├── practice2.md │ │ └── practice3.md │ └── README.md ├── 3. constructor-pattern │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ └── example6.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ ├── practice2.md │ │ └── practice3.md │ └── README.md ├── 4. prototype │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ └── example6.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ ├── practice2.md │ │ └── practice3.md │ └── README.md ├── 5. prototypical-inheritance │ ├── Examples │ │ ├── README.md │ │ ├── example1.md │ │ ├── example2.md │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ └── example6.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ └── practice2.md │ └── README.md ├── 6. event-loop │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ └── example5.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ ├── practice2.md │ │ └── practice3.md │ └── README.md ├── 7. garbage-collector │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ └── example6.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ ├── practice2.md │ │ └── practice3.md │ └── README.md └── README.md ├── basic ├── 1. execution-context │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ ├── example6.js │ │ └── stackOverflow.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ └── practice2.md │ └── README.md ├── 10. browser-storage-and-caching │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ └── example2.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 11. debouncing-and-throttling │ ├── Examples │ │ ├── README.md │ │ ├── example1.html │ │ └── example2.html │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 12. use-strict │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ └── example2.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 13. iife-in-javascript │ ├── Examples │ │ ├── example1.js │ │ └── example2.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 2. scope │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ └── example4.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 3. hoisting │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ ├── example5.js │ │ ├── example6.js │ │ └── example7.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 4. closure │ ├── Examples │ │ ├── Anonymous_fn_with_lexical_scope.js │ │ ├── Closure_In_InnerFunction.js │ │ ├── README.md │ │ ├── closure.js │ │ ├── closure_scope_chain.js │ │ ├── emulating_private_methods_with_closures.js │ │ ├── example_for_understand_usecase_of_closure.js │ │ └── solve_var_functional_scope_issue_using_closure.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 5. call-by-value-and-call-by-reference │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ ├── example3.js │ │ ├── example4.js │ │ └── example5.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ └── practice2.md │ └── README.md ├── 6. callback-and-higher-order-functions │ ├── Examples │ │ ├── README.md │ │ ├── example1.js │ │ ├── example2.js │ │ └── example3.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 7. this-keyword │ ├── Examples │ │ ├── README.md │ │ ├── this_in_constructor_invocation.js │ │ ├── this_in_function_context_with_use_strict.js │ │ ├── this_in_function_context_without_use_strict.js │ │ ├── this_in_global_context.js │ │ ├── this_in_method_invocation.js │ │ └── this_in_method_invocation_with_bind.js │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md ├── 8. event-capturing-and-bubbling │ ├── Examples │ │ ├── README.md │ │ ├── example1.md │ │ ├── example2.md │ │ ├── example3.md │ │ └── example4.md │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ ├── practice1.md │ │ └── practice2.md │ └── README.md ├── 9. event-delegation-and-propagation │ ├── Examples │ │ ├── README.md │ │ ├── example1.md │ │ ├── example2.md │ │ └── example3.md │ ├── Interview Questions │ │ └── README.md │ ├── Practices │ │ ├── README.md │ │ └── practice1.md │ └── README.md └── README.md └── projects ├── README.md ├── big-bang ├── index.html └── index.js ├── blurry-loading ├── index.html ├── script.js └── style.css ├── expanding-cards ├── index.html ├── script.js └── style.css ├── modal ├── app.js ├── index.html └── style.css └── snake-eye ├── index.html └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | .idea 6 | .cloud 7 | .project 8 | tmp/ 9 | typings/ 10 | 11 | # Visual Studio Code 12 | .vscode/* 13 | !.vscode/settings.json 14 | !.vscode/tasks.json 15 | !.vscode/launch.json 16 | !.vscode/extensions.json 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript Bootcamp 2 | 3 | ## উদ্দেশ্য: 4 | জাভাস্ক্রিপ্ট শেখার জন্য নতুনদের পাশাপাশি মিড লেভেল JS ডেভেলপারদের জন্য একটি রোডম্যাপ তৈরি করা। 5 | 6 | ## To get started: 7 | 1. [Basic](basic) 8 | 2. [Advanced](advanced) 9 | 3. [Projects](projects) 10 | -------------------------------------------------------------------------------- /advanced/1. call-apply-bind-methods/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/1. call-apply-bind-methods/Examples/example1.js: -------------------------------------------------------------------------------- 1 | 2 | const person = { 3 | firstName: "Anik", 4 | lastName: "Sajli", 5 | getFullName: function() { 6 | var fullName = this.firstName + " " + this.lastName; 7 | return fullName; 8 | } 9 | } 10 | 11 | function printName(favoriteFood) { 12 | console.log(this.getFullName() + ` loves to eat ${favoriteFood}`); 13 | } 14 | 15 | // This bind method returns a new function which has it's "this" keyword set to the 16 | // provided value in the bind method. 17 | // bind() method example: 18 | 19 | const logName = printName.bind(person, "Pine apple"); // Anik Sajli loves to eat Pine apple 20 | logName(); 21 | 22 | // * call method executes the function immediately 23 | // * doesn't make any copy of the function 24 | // * call method takes additional parameters as well 25 | // call() method example: 26 | 27 | printName.call(person, "Apple"); // Anik Sajli loves to eat Apple 28 | 29 | // the difference between call() and apply() method is call() method accepts 30 | // comma seperated arguments whereas apply method expects the parameters in an array 31 | // apply() method example: 32 | 33 | printName.apply(person, ["Orange"]); // Anik Sajli loves to eat Orange 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /advanced/1. call-apply-bind-methods/Examples/example2.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | We can achieve constructor chaining by using call() and apply(). 4 | We can pick common properties from another constructor function 5 | to be included in our new constructor function by using these methods. 6 | */ 7 | } 8 | 9 | function Food(name, price) { 10 | this.name = name; 11 | this.price = price; 12 | } 13 | 14 | function Burger(name, price) { 15 | Food.call(this, name, price); 16 | this.category = "fastfood"; 17 | } 18 | 19 | function Brownie(name, price) { 20 | Food.call(this, name, price); 21 | this.category = "dessert"; 22 | } 23 | 24 | burger = new Burger("Hamburger", "300"); 25 | brownie = new Brownie("Chocolate brownie", "200"); 26 | console.log(burger); 27 | console.log(brownie); 28 | 29 | { 30 | /* 31 | Output: 32 | { 33 | category: "fastfood" 34 | name: "Hamburger" 35 | price: "300" 36 | } 37 | { 38 | category: "dessert" 39 | name: "Chocolate brownie" 40 | price: "200" 41 | } 42 | */ 43 | } 44 | 45 | // The same behavior can also be achieved by using the apply() method 46 | function Pizza(name, price) { 47 | Food.apply(this, [name, price]); 48 | this.category = "fastfood"; 49 | } 50 | 51 | pizza = new Pizza("Pepperoni Pizza", "500"); 52 | 53 | console.log(pizza); 54 | 55 | { 56 | /* 57 | Output: 58 | { 59 | category: "fastfood" 60 | name: "Pepperoni Pizza" 61 | price: "500" 62 | } 63 | */ 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /advanced/1. call-apply-bind-methods/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | call(), bind() and apply() methods are used for several reasons. 3 | Some of them are: 4 | 1. Create custom value of "this" 5 | 2. Borrowing another objects methods 6 | which means invoking an object’s method on a totally different object 7 | */ 8 | 9 | /* 10 | call() Method 11 | - The first parameter of call() method is an object on which "this" will point to 12 | - Other parameters are variables 13 | */ 14 | 15 | let Team = { 16 | getStatistics : function(league, season){ 17 | return this.name + " are " +this.position+ " in "+ league+" with "+this.points+" points in season "+season; 18 | } 19 | } 20 | 21 | let RealMadrid = { 22 | name: "Real Madrid", 23 | position: "1st", 24 | points: 46 25 | } 26 | 27 | let Barcelona = { 28 | name: "FC Barcelona", 29 | position: "5th", 30 | points: 31 31 | } 32 | 33 | console.log(Team.getStatistics.call(RealMadrid, "Laliga", "2022")); 34 | // Here we set "this" of getStatistics method to RealMadrid object 35 | // Output: Real Madrid are 1st in Laliga with 46 points in season 2022 36 | 37 | console.log(Team.getStatistics.call(Barcelona, "Laliga", "2022")); 38 | // Here we set "this" of getStatistics method to Barcelona object 39 | // Output: FC Barcelona are 5th in Laliga with 31 points in season 2022 40 | 41 | 42 | /* 43 | apply() Method 44 | - The first parameter of apply() method is an object on which "this" will point to 45 | - The second parameter of the apply() method accepts the arguments as an array. 46 | - Which is the only difference between call() and apply() 47 | */ 48 | 49 | let others = ["Laliga", "2022"]; 50 | console.log(Team.getStatistics.apply(RealMadrid, others)); 51 | // Here we set "this" of getStatistics method to RealMadrid object 52 | // On 2nd parameter we used an array to produce the same output 53 | // Output: Real Madrid are 1st in Laliga with 46 points in season 2022 54 | 55 | 56 | /* 57 | bind() method 58 | - bind() method is like call() method 59 | but it returns a bound function which will be invoked later 60 | */ 61 | 62 | let result = Team.getStatistics.bind(Barcelona, "Laliga", "2022"); 63 | console.log(result()) 64 | // Output: FC Barcelona are 5th in Laliga with 31 points in season 2022 65 | // Here we stored the bound function in the result variable 66 | // Then we invoked the returned function later 67 | -------------------------------------------------------------------------------- /advanced/1. call-apply-bind-methods/Examples/example4.js: -------------------------------------------------------------------------------- 1 | // Here are some other use of call(), bind() and apply() methods 2 | 3 | /* 4 | We can use call() to Invoke an Anonymous Function 5 | */ 6 | 7 | const sports = [ 8 | { name: 'Cricket' }, 9 | { name: 'Football' } 10 | ]; 11 | 12 | for(let i=0;i { 14 | console.log("Student name: " + name + "\n" 15 | + "Department name: " + dept + "\n" 16 | + "Roll number: " + roll); 17 | } 18 | } 19 | 20 | return student; 21 | } 22 | 23 | const student1 = studentFactory("Anik", "Software Engineering", "2016831008"); 24 | student1.printStudentDetails(); 25 | 26 | 27 | // output: 28 | // Student name: Anik 29 | // Department name: Software Engineering 30 | // Roll number: 2016831008 31 | 32 | 33 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Examples/example2.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | let's say a company has three types of employees and the salary 4 | for those three positions are predefined. We can create the 5 | employee objects by using the factory pattern. Constructor pattern 6 | has also been used in this example for creating certain objects. 7 | However, the employeeFactory() function has followed the 8 | factory pattern to create employee objects. 9 | */ 10 | } 11 | 12 | function employeeFactory(employeeType, employeeName) { 13 | let employee; 14 | if (employeeType === "fulltime") { 15 | employee = new fulltimeEmployee(employeeName); 16 | } else if(employeeType === "parttime") { 17 | employee = new parttimeEmployee(employeeName); 18 | } else if (employeeType === "temporary") { 19 | employee = new temporaryEmployee(employeeName); 20 | } 21 | employee.printEmployeeDetails = () => { 22 | console.log("Name: " + employee.name + "\n" 23 | + "Salary: " + employee.salary + "\n" 24 | + "Employee Type: " + employee.employeeType) 25 | } 26 | return employee; 27 | } 28 | 29 | function fulltimeEmployee(employeeName) { 30 | this.name = employeeName; 31 | this.salary = 50000; 32 | this.employeeType = "Fulltime Employee"; 33 | } 34 | 35 | function parttimeEmployee(employeeName) { 36 | this.name = employeeName; 37 | this.salary = 30000; 38 | this.employeeType = "Parttime Employee"; 39 | } 40 | 41 | function temporaryEmployee(employeeName) { 42 | this.name = employeeName; 43 | this.salary = 25000; 44 | this.employeeType = "Temporary Employee"; 45 | } 46 | 47 | employee1 = employeeFactory("fulltime", "Fahim"); 48 | employee1.printEmployeeDetails(); 49 | 50 | 51 | 52 | // output: 53 | // Name: Fahim 54 | // Salary: 50000 55 | // Employee Type: Fulltime Employee 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | Its easy to define private methods or property in a factory. 3 | We just need to include them outside of the returned object. 4 | */ 5 | 6 | function person (name) { 7 | function sayDetail(){ 8 | return name + " who loves travelling"; 9 | } 10 | return { 11 | talk: function(){ 12 | console.log('Hello, my name is '+sayDetail()) 13 | } 14 | } 15 | } 16 | 17 | /* 18 | Here in this code sayDetail() is closed inside factory. 19 | This helps us to keep our implementation details encapsulated. 20 | */ 21 | 22 | let person1 = person("Mehedi"); 23 | person1.talk() // Output: Hello, my name is Mehedi who loves travelling 24 | person1.sayDetail() // Output: TypeError: person1.sayDetail is not a function 25 | 26 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Examples/example4.js: -------------------------------------------------------------------------------- 1 | //Factory Pattern মেথড ব্যাবহার করার উদাহরণ 2 | //Live: https://jsfiddle.net/rijans/zhLcbepo/5/ 3 | 4 | function makePersonalHomePage(metaTitle) { 5 | return { 6 | meta_title: metaTitle, 7 | make_html: function () { 8 | console.log('A page with the title of ' + this.meta_title + ' is made!') 9 | } 10 | } 11 | } 12 | 13 | const homePageOfJaber = makePersonalHomePage('Jaber\'s Home'); 14 | console.log(homePageOfJaber.make_html()); 15 | 16 | 17 | const homePageOfVivaSoft = makePersonalHomePage('VivaSoft\'s Home'); 18 | console.log(homePageOfVivaSoft.make_html()); 19 | 20 | //ফলাফল: 21 | //A page with the title of Jaber's Home is made!" 22 | //A page with the title of VivaSoft's Home is made!" -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Examples/example5.js: -------------------------------------------------------------------------------- 1 | //Factory Pattern মেথড ব্যাবহার করার উদাহরণ 2 | //Live: https://jsfiddle.net/rijans/vr31aj7x/ 3 | 4 | function buildCustomPC(cpu, ram, motherBoard, others) { 5 | return { 6 | cpu: cpu, 7 | ram: ram, 8 | motherBoard: motherBoard, 9 | others: others, 10 | buildPC: function () { 11 | console.log('A PC with RAM ' + ram + ', CPU ' + cpu + ' and motherboard ' + motherBoard + ' is built!') 12 | } 13 | } 14 | } 15 | 16 | const pc1 = buildCustomPC('Core i7 11700', 'Corsair 16GB 3200GHz', 'Asus Gaming G8', {}); 17 | console.log(pc1.buildPC()); 18 | 19 | 20 | const pc2 = buildCustomPC('Apple M1 Pro', 'TSC 16GB Module', 'Foxcon M1 Mainboard', {}); 21 | console.log(pc2.buildPC()); 22 | 23 | //ফলাফল: 24 | //"A PC with RAM Corsair 16GB 3200GHz, CPU Core i7 11700 and motherboard Asus Gaming G8 is built!" 25 | //"A PC with RAM TSC 16GB Module, CPU Apple M1 Pro and motherboard Foxcon M1 Mainboard is built!" -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | Consider the below code where we have created 2 Vehicle objects on the fly. 2 | How can you improve this code by using the factory design pattern? 3 | 4 | ```javascript 5 | const Vehicle1 = { 6 | manufacturer: "Toyota", 7 | PlateNO: 12345, 8 | startEngine () {console.log("Starting engine."}, 9 | drive () {console.log("Driving car...")} 10 | } 11 | 12 | 13 | const Vehicle2 = { 14 | manufacturer: "Ford", 15 | PlateNO: 13345, 16 | startEngine () {console.log("Starting engine."}, 17 | drive () {console.log("Driving car...")} 18 | } 19 | ``` -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | What will be the output of this code? 3 | How can we access the functions inside factory function? 4 | 5 | ```javascript 6 | function person (name, sport) { 7 | function saySport(){ 8 | return " who loves "+sport; 9 | } 10 | function sayName(){ 11 | return "My name is "+ name +saySport(); 12 | } 13 | return { 14 | talk: function(){ 15 | console.log('Hello, '+sayName()) 16 | } 17 | } 18 | } 19 | 20 | let person1 = person("Mehedi", "Cricket"); 21 | console.log(person1.saySport()) 22 | ``` 23 | -------------------------------------------------------------------------------- /advanced/2. factory-pattern/Practices/practice3.md: -------------------------------------------------------------------------------- 1 | নিচের কোড টি খেয়াল করুন। এটাতে factory pattern ব্যাবহার করা হয়েছে। আপনি কিভাবে এটাকে আর ভাল করতে পারেন? সাথে dynamic parameters দিয়ে? 2 | 3 | ```javascript 4 | function pc1() { 5 | return { 6 | manufacturer: "ASUS", 7 | cpu: "Intel Core i9 11900", 8 | ram: "Corsair 16GB 3200 GHz", 9 | buildPC: function () { 10 | console.log('A PC with manufacturer ' + this.manufacturer + ' CPU ' + this.cpu + ' RAM ' + this.ram + ' is built!'); 11 | } 12 | } 13 | 14 | } 15 | 16 | function pc2() { 17 | return { 18 | manufacturer: "MSI", 19 | cpu: "Apple M1 Pro Max", 20 | ram: "TSC 16GB 3600GHz", 21 | buildPC: function () { 22 | console.log('A PC with manufacturer ' + this.manufacturer + ' CPU ' + this.cpu + ' RAM ' + this.ram + ' is built!'); 23 | } 24 | } 25 | } 26 | 27 | let newPC1 = pc1(); 28 | console.log(newPC1.buildPC()); 29 | 30 | let newPC2 = pc2(); 31 | console.log(newPC2.buildPC()); 32 | 33 | 34 | ``` -------------------------------------------------------------------------------- /advanced/2. factory-pattern/README.md: -------------------------------------------------------------------------------- 1 | ### Factory Pattern 2 | 3 | আজকের আলোচনার বিষয় হচ্ছে জাভাস্ক্রিপ্টের Factory Pattern. জাভাস্ক্রিপ্ট প্রোগ্রামার বা ডেভেলপার হিসাবে Factory Pattern সম্পর্কে পরিষ্কার ধারণা থাকা খুব প্রয়োজন। তাই চেষ্টা করবো আজকে practical উদাহরণ দিয়ে এই মেথডকে নিয়ে আলোচনা করতে। আশা করি, আজকের পর থেকে এই Factory Pattern নিয়ে কাজ করতে কখনো সমস্যা হবে না। 4 | 5 | ধরা যাক, আমাদের কাছে একটি circle নামে একটি Object আছে। circle Object টিতে draw নামে একটি মেথড এবং radius নামে একটি variable আছে। 6 | 7 | ```js 8 | 9 | const circle = { 10 | radius: 1, 11 | draw: function draw() { 12 | console.log(`Circle radius is ${this.radius}`); 13 | }, 14 | }; 15 | console.log(circle.draw()); 16 | 17 | 18 | /// output: Circle radius is 1 19 | 20 | ``` 21 | উপরের কোড থেকে দেখতে পাচ্ছি যে, circle Object এর draw মেথডটিকে call করে আমরা circle এর radius টি print করতে পারছি। এখন আমরা যদি circle2 নামে এ একই Functionality এর আরও একটি Object create করতে চাই তাহলে ঠিক একই রকম করে আবার নতুন করে Object এর structure টা লিখতে হবে। অনেকটা এই রকম করে, 22 | 23 | ```js 24 | 25 | const circle2 = { 26 | radius: 5, 27 | draw: function draw() { 28 | console.log(`Circle2 radius is ${this.radius}`); 29 | }, 30 | }; 31 | console.log(circle2.draw()); /// output: Circle2 radius is 5 32 | 33 | ``` 34 | 35 | circle এবং circle2 এই দুইটি Object এর কোড যদি একটু লক্ষ্য করি তবে দেখব যে, এখানে বেশ repetative কোড আছে। তাছাড়া এখানে মাত্র একটি মেথড রয়েছে কিন্তু যদি এইখানে আরও অনেক মেথড থাকত এবং প্রত্যেক মেথডে অনেক কোড থাকত তবে আমাদের একই কোড বারবার লিখতে হত। এছাড়াও যদি কোনও মেথডের লজিক পরিবর্তন করার দরকার হয় তবে একাধিক জায়গায় কোড পরিবর্তন করতে হবে যা খুবই সময় সাপেক্ষ এবং বিরক্তিকর। তাই না। 36 | সুতরাং যদি আমাদের Object এ লজিক থাকে তবে আমাদের এখন ভিন্ন একটা পদ্ধতি দরকার যার মাধ্যমে আমরা Object বানাতে পারি। ঠিক এই সময়ে আমরা Factory বা Constructor ফাংশন ব্যবহার করি। এই আলোচনাতে আমরা Factory ফাংশন নিয়ে কথা বলব। 37 | 38 | ### Factory Pattern 39 | 40 | সহজভাবে বলতে গেলে, Factory Function এমন একটি ফাংশন যা Class বা new Keyword এর জটিলতা ছাড়াই Object তৈরি করতে পারে । অন্যভাবে বলতে গেলে, জাভাস্ক্রিপ্টের যেকোন Function-ই Object return করতে পারে কিন্তু যখন কোন Function এই একই কাজ new Keyword ছাড়া করতে পারে তাকেই আমরা Factory Function বলব। Factory Function ব্যবহার করে Object তৈরি করার প্রক্রিয়াই আসলে Factory Pattern. 41 | 42 | Factory যেমন বিভিন্ন জিনিস তৈরি করতে পারে ঠিক তেমনি জাভাস্ক্রিপ্টের Factory Function বিভিন্ন Object তৈরি করতে পারে। জটিল মনে হলেও ভয় পাওয়ার কিছু নেই একটা উদাহরণ দেখলে সব ক্লিয়ার হয়ে যাবে। 43 | 44 | 45 | প্রথমে আমারা একটি Function বানাবো যার নাম হবে createCircle. 46 | 47 | ```js 48 | 49 | function createCircle(){ 50 | } 51 | 52 | ``` 53 | এরপর createCircle Factory Function এর মধ্যে আমরা আমাদের circle Object এর Defination টা বসিয়ে return করব। 54 | 55 | ```js 56 | 57 | function createCircle(){ 58 | const circle = { 59 | radius: 1, 60 | draw: function draw() { 61 | console.log(`Circle radius is ${this.radius}`); 62 | }, 63 | }; 64 | return circle; 65 | } 66 | 67 | ``` 68 | 69 | এখন যখনই আমরা createCircle Factory Function কে call করব আমরা একটা circle Object পাব। কিন্তু আমারা এখানে circle Object এর radius এর মানটা hardcoded করে রেখেছি ফলে যে circle Object তৈরি হবে তার radius সবসময় একই হবে। সুতরাং আমাদের কোডটাকে ডাইনামিক করতে হবে যাতে আমরা যে কোন radius এর circle Object তৈরি করতে পারি। এক্ষেত্রে আমরা createCircle Factory Function এ প্যারামিটার হিসেবে radius এর মানটা পাঠাতে পারি। 70 | 71 | ```js 72 | 73 | function createCircle(radius){ 74 | const circle = { 75 | radius: radius, 76 | draw: function draw() { 77 | console.log(`Circle radius is ${this.radius}`); 78 | }, 79 | }; 80 | return circle; 81 | } 82 | 83 | const circle1 = createCircle(5); 84 | console.log(circle1.draw()); 85 | 86 | 87 | // 88 | // output: Circle radius is 5 89 | // 90 | // 91 | 92 | ``` 93 | 94 | Factory Function এর সৌন্দর্য হল আমরা আমাদের Object এর লজিকগুলো এক জায়গায় সংজ্ঞায়িত করেছি। সুতরাং আমরা এখন createCircle Factory Function কে বিভিন্ন মান বা বিভিন্ন আর্গুমেন্ট দিয়ে কল করে বিভিন্ন circle Object পেতে পারি। কিন্তু একটু লক্ষ্য করলে দেখা যাবে যে, আমরা draw মেথড শুধুমাত্র একটি জায়গায় সংজ্ঞায়িত করেছি। সুতরাং, যদি এই পদ্ধতিতে যদি কোন Bug থাকে যা ভবিষ্যতে আমাদের ঠিক করতে হবে সেখানে শুধুমাত্র একটি জায়গাতে সংশোধন করলেই হবে। নিচের উদাহরণটি দেখলে ব্যাপারটি আরও পরিষ্কার হবে। 95 | 96 | ```js 97 | 98 | function createCircle(radius){ 99 | const circle = { 100 | radius: radius, 101 | draw: function draw() { 102 | console.log(`Circle radius is ${this.radius}`); 103 | }, 104 | }; 105 | return circle; 106 | } 107 | 108 | const circle1 = createCircle(5); 109 | console.log(circle1.draw()); 110 | const circle2 = createCircle(10); 111 | console.log(circle2.draw()); 112 | 113 | // 114 | // output: 115 | // Circle radius is 5 116 | // Circle radius is 10 117 | // 118 | 119 | 120 | ``` 121 | 122 | উপরের কোড এর আউটপুটটা দেখুন, দুইটি circle Object তৈরি হয়েছে। এভাবে যত খুশি তত circle Object তৈরি করা যাবে। এই ছিল Factory Pattern নিয়ে আজকের লেখা। হ্যাপি কোডিং। 123 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example1.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | Counstructor pattern can be used to create new objects. As you may know that factory pattern 4 | can also be used for the same purpose. But the basic difference between these two process 5 | is in case of factory pattern the function returns an object but when we're using 6 | constructor pattern, we'll be using the 'new' keyword to create an empty object and 7 | then add our desired properties to that object with the help of 'this' keyword. 8 | 9 | In our code below, the 'this' keyword used in the CreateLaptop() function points to the 10 | empty object which is being created by the 'new' keyword below. 11 | */ 12 | } 13 | 14 | function CreateLaptop(brand, model, ram, storage) { 15 | this.brand = brand; 16 | this.model = model; 17 | this.ram = ram; 18 | this.storage = storage; 19 | this.toString = function(){ 20 | return `This ${this.brand} ${this.model} laptop has ${this.ram} RAM and ${this.storage} storage.` 21 | } 22 | } 23 | 24 | const laptop1 = new CreateLaptop("Dell", "Inspiron 15", "8 GB", "1 TB"); 25 | console.log(laptop1.toString()); 26 | 27 | { 28 | /* 29 | Output: 30 | This Dell Inspiron 15 laptop has 8 GB RAM and 1 TB storage. 31 | */ 32 | } 33 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example2.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | In the example below, we have used constructors with prototype. 4 | Just like any other objects in javascript, functions also contain 'prototype' 5 | objects. 6 | The two car objects (car1 and car2) that we created here will contain the same 7 | instance of the 'toString' property that we added to the 'prototype' object of 'Car'. 8 | */ 9 | } 10 | function Car(brand, model, price) { 11 | this.brand = brand; 12 | this.model = model; 13 | this.price = price; 14 | } 15 | 16 | Car.prototype.toString = function () { 17 | return this.brand + ' ' + this.model + " is worth " + this.price + " tk"; 18 | }; 19 | 20 | car1 = new Car('Toyota', 'Corolla', 2000000); 21 | car2 = new Car('Lamborghini', 'Silhouette', 30000000); 22 | 23 | console.log(car1.toString()); 24 | console.log(car2.toString()); 25 | 26 | { 27 | /* 28 | Output: 29 | Toyota Corolla is worth 2000000 tk 30 | Lamborghini Silhouette is worth 30000000 tk 31 | */ 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | Here 'mehedi' is an object of contructor function 'Person' and 3 | we can also add extra properties to the object which 4 | will not be property of constructor 'Person' 5 | */ 6 | 7 | function Person (firstName, lastName) { 8 | this.firstName = firstName; 9 | this.lastName = lastName; 10 | this.fullName =function () { 11 | return this.firstName + this.lastName; 12 | } 13 | } 14 | 15 | let mehedi = new Person("Mehedi", "Zamadar"); 16 | mehedi.age = 24; 17 | console.log(mehedi.age) // Output: 24 18 | 19 | mehedi.hello = function (){ 20 | return "Hello"; 21 | } 22 | console.log(mehedi.hello()) // Output: Hello -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example4.js: -------------------------------------------------------------------------------- 1 | /* 2 | We know while using the constructor pattern, 3 | we need to manage the context of this by using the new keyword. 4 | There is another technique which avoids this. 5 | Which is using Closure with getters and setters. 6 | */ 7 | 8 | function Rectangle(length, width){ 9 | let _length = length; 10 | let _width = width; 11 | 12 | let rectangle = {}; 13 | rectangle.Area = function(){ 14 | return _length * _width; 15 | } 16 | // Getter/setters 17 | rectangle.Length = function(value){ 18 | if(!arguments.length) return _length; 19 | _length = value; 20 | return rectangle; 21 | } 22 | 23 | rectangle.Width = function(value){ 24 | if(!arguments.length) return _width; 25 | _width = value; 26 | return rectangle; 27 | } 28 | return rectangle; 29 | 30 | } 31 | 32 | let rectangle1 = Rectangle(10, 10); // no 'new' keyword 33 | console.log(rectangle1.Area()) // Output: 100 34 | 35 | rectangle1.Length(100) 36 | rectangle1.Width(50) 37 | console.log(rectangle1.Area()) // Output: 5000 38 | 39 | /* 40 | With a reference of 'rectangle1' object we can 41 | set Length and Width property to any value. 42 | */ -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example5.js: -------------------------------------------------------------------------------- 1 | //Example for Javascript Constructor Pattern Function 2 | //Constructor Pattern মেথড ব্যাবহার করার উদাহরণ 3 | 4 | //Live: https://jsfiddle.net/rijans/4drfo3qw/ 5 | 6 | function BuildCustomPC(cpu, ram, motherBoard, others) { 7 | 8 | this.cpu = cpu; 9 | this.ram = ram; 10 | this.motherBoard = motherBoard; 11 | this.others = others; 12 | this.buildPC = function () { 13 | console.log('A PC with RAM ' + ram + ', CPU ' + cpu + ' and motherboard ' + motherBoard + ' is built!') 14 | } 15 | 16 | } 17 | 18 | const pc1 = new BuildCustomPC('Core i7 11700', 'Corsair 16GB 3200GHz', 'Asus Gaming G8', {}); 19 | console.log(pc1.buildPC()); 20 | 21 | 22 | const pc2 = new BuildCustomPC('Apple M1 Pro', 'TSC 16GB Module', 'Foxcon M1 Mainboard', {}); 23 | console.log(pc2.buildPC()); 24 | 25 | //ফলাফল: 26 | //"A PC with RAM Corsair 16GB 3200GHz, CPU Core i7 11700 and motherboard Asus Gaming G8 is built!" 27 | //"A PC with RAM TSC 16GB Module, CPU Apple M1 Pro and motherboard Foxcon M1 Mainboard is built!" -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Examples/example6.js: -------------------------------------------------------------------------------- 1 | //Constructor Pattern মেথড ব্যাবহার করার উদাহরণ 2 | //Live: https://jsfiddle.net/rijans/opu1xckt/ 3 | 4 | function CreateUser(username, fName, lName, email) { 5 | this.username = username; 6 | this.fName = fName; 7 | this.lName = lName; 8 | this.email = email; 9 | this.createUser = function () { 10 | console.log('A User with username ' + this.username + ', first name ' + this.fName + ' and last name ' + this.lName + ' is created!') 11 | } 12 | } 13 | 14 | const user1 = new CreateUser('jaber', 'Jaber', 'Al Nahian', 'j@gmail.com'); 15 | console.log(user1.createUser()); 16 | 17 | 18 | const user2 = new CreateUser('tareq', 'Shafiul Hasan', 'Tareq', 't@gmail.com'); 19 | console.log(user2.createUser()); 20 | 21 | //ফলাফল: 22 | //"A User with username jaber, first name Jaber and last name Al Nahian is created!" 23 | //"A User with username tareq, first name Shafiul Hasan and last name Tareq is created!" -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | Consider the below code snippet. Try to guess which design pattern was used in this code. 2 | Convert this code to implement the same functionailty by using Constructor pattern. 3 | 4 | ```javascript 5 | function createVehicle(brand, model, price) { 6 | const vehicle = { 7 | brand: brand, 8 | model: model, 9 | price: price, 10 | printVehicleDetails: () => { 11 | console.log("Brand: " + brand + "\n" 12 | + "Model: " + model + "\n" 13 | + "Price: " + price + " tk"); 14 | } 15 | } 16 | 17 | return vehicle; 18 | } 19 | 20 | const vehicle1 = createVehicle("Toyota", "Corolla", "2000000"); 21 | vehicle1.printVehicleDetails(); 22 | ``` -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | What will be the output if we dont use 'new' keyword 3 | while creating new object of constructor function? 4 | 5 | ```javascript 6 | function Team (name, country){ 7 | this.name = name; 8 | this.country = country; 9 | } 10 | 11 | Team.prototype.detail = function (){ 12 | return this.name + " is from " + this.country; 13 | } 14 | 15 | let team1 = Team("Manchester City", "England"); 16 | console.log(team1.detail()) 17 | ``` -------------------------------------------------------------------------------- /advanced/3. constructor-pattern/Practices/practice3.md: -------------------------------------------------------------------------------- 1 | নিচের কোডটি লক্ষ করুন। দুটি ইউজার বানানর জন্য দুটি constructor function বানানো হয়েছে। এহাকে normalize করুন with dynamic parameters. 2 | 3 | ````javascript 4 | function CreateUser1() { 5 | this.username = 'jaber'; 6 | this.fName = 'Jaber'; 7 | this.lName = 'Al Nahian'; 8 | this.email = 'j@gmail.com'; 9 | this.createUser = function () { 10 | console.log('A User with username ' + this.username + ', first name ' + this.fName + ' and last name ' + this.lName + ' is created!') 11 | } 12 | } 13 | 14 | function CreateUser2() { 15 | this.username = 'tareq'; 16 | this.fName = 'Shaiful Hasan'; 17 | this.lName = 'Tareq'; 18 | this.email = 't@gmail.com'; 19 | this.createUser = function () { 20 | console.log('A User with username ' + this.username + ', first name ' + this.fName + ' and last name ' + this.lName + ' is created!') 21 | } 22 | } 23 | 24 | const user1 = new CreateUser1(); 25 | console.log(user1.createUser()); 26 | 27 | 28 | const user2 = new CreateUser2(); 29 | console.log(user2.createUser()); 30 | ```` -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example1.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | In the example below, the function getFullName() will be available 4 | in every new Name object automatically because we have put this 5 | function inside the prototype object of the Name() constructor function. 6 | */ 7 | } 8 | 9 | function Name(firstName, lastName) { 10 | this.firstName = firstName; 11 | this.lastName = lastName; 12 | } 13 | 14 | Name.prototype.getFullName = function() { 15 | return `${this.firstName} ${this.lastName}`; 16 | } 17 | 18 | var name1 = new Name('Anik', 'Sajli'); 19 | console.log(name1.getFullName()); // Anik Sajli 20 | 21 | var name2 = new Name('Fahim', 'Ahmed'); 22 | console.log(name2.getFullName()); // Fahim Ahmed 23 | 24 | 25 | -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example2.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | One fun thing about prototypes is even the prototype of a function has 4 | it's own prototype. This is called prototype chaining. In the example below, 5 | the nesting of prototypes can be used to add properties to different layers of 6 | prototype objects which are accessible to us later. We have added the property 7 | 'profession' to the prototype of Person's prototype. As you can see below that 8 | we are also able to update the value of that property later. 9 | */ 10 | } 11 | 12 | function Person(name, age) { 13 | this.name = name; 14 | this.age = age; 15 | } 16 | 17 | Person.__proto__.__proto__.profession = 'Software Engineer'; 18 | person1 = new Person("Anik", 25); 19 | console.log(person1.profession); // Software Engineer 20 | person1.profession = 'Businessman'; 21 | console.log(person1.profession); // Businessman -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | We know that we can access the defined method on 3 | the instances of the object. Like this one below: 4 | */ 5 | 6 | function Team(name) { 7 | this.name = name; 8 | } 9 | 10 | Team.prototype.getDetails = function() { 11 | return `${this.name} plays football`; 12 | } 13 | 14 | // In this 'team1' and 'team2' instance of Team, 15 | // we can access getDetails() method 16 | 17 | let team1 = new Team('Real Madrid'); 18 | console.log(team1.getDetails()); 19 | // Output: Real Madrid plays football 20 | let team2 = new Team('Barcelona'); 21 | console.log(team2.getDetails()); 22 | // Output: Barcelona plays football 23 | 24 | 25 | /* 26 | But if we define methods in an individual object (instances of Team) 27 | then we can only access those methods from the individual object 28 | */ 29 | 30 | team1.league = function(){ 31 | return "La Liga" 32 | } 33 | 34 | console.log(team1.league()) 35 | // Output: La Liga 36 | 37 | console.log(team2.league()) 38 | // Output: TypeError: team2.league is not a function 39 | 40 | -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example4.js: -------------------------------------------------------------------------------- 1 | /* 2 | Let’s add a new method to the object person1 3 | with the same name as the method in the Person.prototype object 4 | */ 5 | function Person(name){ 6 | this.name = name; 7 | } 8 | Person.prototype.City = function(){ 9 | return `${this.name} is from Dhaka`; 10 | } 11 | 12 | let person1 = new Person("Mehedi"); 13 | person1.City = function (){ 14 | return `${this.name} is from CTG`; 15 | } 16 | 17 | console.log(person1.City()) 18 | 19 | /* Output: Mehedi is from CTG 20 | 21 | Because the person1 object has the City() method, 22 | JavaScript just executes it immediately without 23 | looking it up in the prototype chain. 24 | */ -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example5.js: -------------------------------------------------------------------------------- 1 | //Prototype মেথড ব্যাবহার করে object construct করার উদাহরণ 2 | //Live: https://jsfiddle.net/rijans/tumcyw5p/1/ 3 | 4 | function CustomPC(cpu, ram, board) { 5 | this.cpu = cpu; 6 | this.ram = ram; 7 | this.board = board; 8 | // this.buildPC = function () { 9 | // return 'A PC with CPU ' + this.cpu + ', RAM ' + this.ram + ' and Motherboard ' + this.board + ' is built!' 10 | // } 11 | //আমরা উপরের function কে prototype হিসাবে যোগ করব 12 | } 13 | 14 | CustomPC.prototype.buildPC = function () { 15 | return 'A PC with CPU ' + this.cpu + ', RAM ' + this.ram + ' and Motherboard ' + this.board + ' is built!' 16 | } 17 | 18 | const pc1 = new CustomPC('Intel Core i9 11900', 'Corsair 16GB 3200GHz', 'ASUS G1 Sniper'); 19 | console.log(pc1.buildPC()); 20 | //ফলাফল: A PC with CPU Apple M1 Pro Max, RAM Corsair 16GB 3200GHz and Motherboard Foxcon M1 Board is built!" 21 | 22 | const pc2 = new CustomPC('Apple M1 Pro Max', 'Corsair 16GB 3200GHz', 'Foxcon M1 Board'); 23 | console.log(pc2.buildPC()); 24 | //ফলাফল: A PC with CPU Apple M1 Pro Max, RAM Corsair 16GB 3200GHz and Motherboard Foxcon M1 Board is built!" 25 | -------------------------------------------------------------------------------- /advanced/4. prototype/Examples/example6.js: -------------------------------------------------------------------------------- 1 | //Prototype মেথড ব্যাবহার করে object construct করার উদাহরণ 2 | //Live: https://jsfiddle.net/rijans/z0mecdv3/ 3 | 4 | function CustomBike(cc, bikeType, headlightType) { 5 | this.cc = cc; 6 | this.bikeType = bikeType; 7 | this.headlightType = headlightType; 8 | // this.buildBike = function () { 9 | // return 'A Bike with CC ' + this.cc + ', type ' + this.bikeType + ' and Headlight ' + this.headlightType + ' is built!' 10 | // } 11 | //আমরা উপরের function কে prototype হিসাবে যোগ করব 12 | } 13 | 14 | CustomBike.prototype.buildBike = function () { 15 | return 'A Bike with CC ' + this.cc + ', type ' + this.bikeType + ' and Headlight ' + this.headlightType + ' is built!' 16 | } 17 | 18 | const pc1 = new CustomBike('150', 'Sports', 'LED Projector'); 19 | console.log(pc1.buildBike()); 20 | //ফলাফল: A Bike with CC 150, type Sports and Headlight LED Projector is built!" 21 | 22 | const pc2 = new CustomBike('150', 'Commuter', 'LED Regular'); 23 | console.log(pc2.buildBike()); 24 | //ফলাফল: A Bike with CC 150, type Commuter and Headlight LED Regular is built!" -------------------------------------------------------------------------------- /advanced/4. prototype/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/4. prototype/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/4. prototype/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | Consider the code snippet below. Now suppose I want to create multiple car objects which might have some new properties. All the car objects must have the 'getCarBrand' 2 | and 'getCarPrice' methods as it's property. But i don't want these 2 methods to be recreated in the memory every time a car object is created. How can you achieve this? 3 | 4 | 5 | ```javascript 6 | let car = {}; 7 | car.brand = 'Toyota'; 8 | car.price = 2000000; 9 | car.getCarBrand = function () { 10 | return this.brand; 11 | } 12 | 13 | car.getCarPrice = function () { 14 | return this.price; 15 | } 16 | 17 | console.log(car.getCarBrand()); 18 | console.log(car.getCarPrice()); 19 | ``` 20 | -------------------------------------------------------------------------------- /advanced/4. prototype/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | Consider the code below. Can the person1 object directly access the 'prototype' object? 3 | What do you think the output will be? 4 | 5 | ```javascript 6 | function Person(name){ 7 | this.name = name; 8 | } 9 | Person.prototype.City = function(){ 10 | return `${this.name} is from Dhaka`; 11 | } 12 | 13 | let person1 = new Person("Mehedi"); 14 | 15 | console.log(person1.prototype.City()) 16 | ``` -------------------------------------------------------------------------------- /advanced/4. prototype/Practices/practice3.md: -------------------------------------------------------------------------------- 1 | নিচের কোডটিতে prototype implement করুন: 2 | 3 | ````js 4 | function CustomPC(cpu, ram, board) { 5 | this.cpu = cpu; 6 | this.ram = ram; 7 | this.board = board; 8 | this.buildPC = function () { 9 | return 'A PC with CPU ' + this.cpu + ', RAM ' + this.ram + ' and Motherboard ' + this.board + ' is built!' 10 | } 11 | } 12 | 13 | const pc1 = new CustomPC('Intel Core i9 11900', 'Corsair 16GB 3200GHz', 'ASUS G1 Sniper'); 14 | console.log(pc1.buildPC()); 15 | 16 | const pc2 = new CustomPC('Apple M1 Pro Max', 'Corsair 16GB 3200GHz', 'Foxcon M1 Board'); 17 | console.log(pc2.buildPC()); 18 | ```` -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example1.md: -------------------------------------------------------------------------------- 1 | ```js 2 | function Animal (name, energy) { 3 | this.name = name; 4 | this.energy = energy; 5 | } 6 | 7 | Animal.prototype.eat = function (amount) { 8 | console.log(`${this.name} is eating.`); 9 | this.energy += amount; 10 | } 11 | 12 | Animal.prototype.sleep = function (length) { 13 | console.log(`${this.name} is sleeping.`); 14 | this.energy += length; 15 | } 16 | 17 | Animal.prototype.play = function (length) { 18 | console.log(`${this.name} is playing.`); 19 | this.energy -= length; 20 | } 21 | 22 | function Dog (name, energy, breed) { 23 | Animal.call(this, name, energy); 24 | 25 | this.breed = breed; 26 | } 27 | 28 | Dog.prototype = Object.create(Animal.prototype); 29 | 30 | Dog.prototype.bark = function () { 31 | console.log('Woof Woof!'); 32 | this.energy -= .1; 33 | } 34 | 35 | const charlie = new Dog('Charlie', 10, 'Goldendoodle'); 36 | console.log(charlie.constructor); 37 | ``` 38 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example2.md: -------------------------------------------------------------------------------- 1 | ```js 2 | function Person(firstName, lastName, age, gender, interests) { 3 | this.name = { firstName, lastName }; 4 | this.age = age; 5 | this.gender = gender; 6 | this.interests = interests; 7 | }; 8 | 9 | function Teacher(firstName, lastName, age, gender, interests, subject) { 10 | Person.call(this, firstName, lastName, age, gender, interests); 11 | 12 | this.subject = subject; 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | We can use prototype chain to solve this kind of problems 3 | */ 4 | 5 | let user = { 6 | name: "name", 7 | email: "email", 8 | id: 00000, 9 | showAccess: true 10 | } 11 | 12 | let singleUser = { 13 | __proto__ : user, 14 | ads: true 15 | } 16 | 17 | let premiumUser = { 18 | __proto__ : singleUser, 19 | ads: false, 20 | mutiScreen : true 21 | } 22 | 23 | /* 24 | we created a new object user_me where 25 | we used three level of prototypical inheritance. 26 | we can see that user_me object has access to data throughout the chain. 27 | */ 28 | let user_me = { 29 | __proto__ : premiumUser, 30 | name : "Mehedi", 31 | email: "meheditcf@gmail.com", 32 | id: 001 33 | } 34 | 35 | console.log(user_me.mutiScreen) // Output: true 36 | console.log(user_me.ads) // Output: false 37 | console.log(user_me.showAccess) // Output: true -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example4.js: -------------------------------------------------------------------------------- 1 | /* 2 | No matter where the method is found: in an object or its prototype. 3 | In a method call, this is always the object before the dot. 4 | */ 5 | 6 | let animal = { 7 | sleep(){ 8 | this.isSleeping = true; 9 | } 10 | } 11 | 12 | let cat = { 13 | name: "Billu", 14 | __proto__ : animal 15 | } 16 | 17 | cat.sleep() 18 | console.log(cat.isSleeping) // Output: true 19 | /* 20 | As we called the method as cat.sleep(), 21 | 'this' references to cat object. Thats why in the 22 | code below we get undefined. 23 | */ 24 | console.log(animal.isSleeping) // Output: undefined -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example5.js: -------------------------------------------------------------------------------- 1 | //Prototypical Inheritance এর একটি উদ্বাহরও দেখান হল। 2 | 3 | let smartPhone = { 4 | hasCamera: true 5 | } 6 | 7 | let nokiaPhone = { 8 | name: "Nokia 1100", 9 | __proto__ : smartPhone 10 | } 11 | 12 | console.log(nokiaPhone.hasCamera); 13 | //ফলাফল: true -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Examples/example6.js: -------------------------------------------------------------------------------- 1 | //Prototypical Inheritance এর একটি উদ্বাহরও দেখান হল। 2 | 3 | let plant = { 4 | hasLeaf: 'yes' 5 | } 6 | 7 | let cactus = { 8 | name: "Cactus", 9 | __proto__ : plant 10 | } 11 | 12 | console.log(cactus.hasLeaf); 13 | //ফলাফল: true -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | What do you think the output of this code will be? 3 | And why? 4 | 5 | ```js 6 | function House () { 7 | this.height= 100; 8 | this.width= 50; 9 | } 10 | 11 | let house1 = new House(); 12 | House.prototype.height = 200; 13 | console.log(house1.height) 14 | ``` 15 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | নিচের কোডটিতে Prototypical Inheritance Implement করুন 2 | 3 | ````js 4 | let plant = { 5 | hasLeaf: true 6 | } 7 | 8 | let cactus = { 9 | name: "Cactus", 10 | hasLeaf : true 11 | } 12 | 13 | console.log(cactus.hasLeaf); 14 | ```` 15 | -------------------------------------------------------------------------------- /advanced/5. prototypical-inheritance/README.md: -------------------------------------------------------------------------------- 1 | ### Prototypical Inheritance 2 | 3 | আজকের আলোচনার বিষয় হচ্ছে জাভাস্ক্রিপ্টের Prototypical Inheritance. গত আলোচনাতে আমারা জাভাস্ক্রিপ্টের Prototype pattern নিয়ে আলোচনা করেছি। জাভাস্ক্রিপ্ট প্রোগ্রামার বা ডেভেলপার হিসাবে Prototypical Inheritance সম্পর্কে পরিষ্কার ধারণা থাকা খুবই জরুরী। তাই চেষ্টা করবো আজকে কিছু উদাহরণ দিয়ে Prototypical Inheritance নিয়ে একটু লেখতে। চলুন শুরু করা যাক। 4 | 5 | ### Prototypical Inheritance কি? 6 | 7 | সহজভাবে বলতে গেলে Prototypical Inheritance বলতে একটি Object যখন অন্য একটি Object এর প্রপার্টিকে অ্যাক্সেস করতে পারে তাকেই বুঝায়। আমরা জানি যে, জাভাস্ক্রিপ্টের Prototype এর মধ্যে যে কোন Object এ নতুন প্রপার্টি বা মেথড যোগ করা যায়; আমারা তখন আমাদের জাভাস্ক্রিপ্ট কোডে Prototype থেকে এই প্রপার্টিগুলো Inherite করার জন্য বলে দিতে পারি। একটি Object অন্য Object এর প্রপার্টি বা মেথডগুলোকে পুনরায় ব্যবহার করতে Prototypical Inheritance সাহায্য করে। 8 | 9 | সকল জাভাস্ক্রিপ্ট Object ই কোন না কোন প্রপার্টি বা মেথড prototype থেকে Inherit করে থাকে। উদাহরণস্বরূপ, 10 | ১। Date Object, Date.prototype থেকে Inherit করে থাকে। 11 | ২। Array Object, Array.prototype theke Inherit করে থাকে। 12 | আর এই Prototype chain এর সবার উপর থাকে Object.prototype. Date Object, Array Object সবাই Object.prototype কে Inherite করে। 13 | 14 | চলুন, এখন সরাসরি Prototypical Inheritance বুঝার চেষ্টা করি কিছু practical উদাহরন এর মাধ্যমে। 15 | 16 | আসুন, একটি `Rectangle constructor` তৈরি করা যাক। 17 | 18 | ```js 19 | function Rectangle(width, height) { 20 | this.width = width; 21 | this.height = height; 22 | } 23 | ``` 24 | 25 | এখন যদি আমারা `Rectangle constructor` দিয়ে একটা Object তৈরি করতে চাই তবে কি করে করব। নিশ্চয়ই মনে আছে। 26 | 27 | ```js 28 | let rect = new Rectangle(3, 4); 29 | rect.width; // Now the width of Rectangle is 3 30 | rect.height; // And the height of that rectangle is 4 31 | ``` 32 | 33 | এখন আমরা এই `Rectangle constructor` এর মধ্যে একটা মেথড তৈরি করব। মেথডটির নাম `area` দেয়া যেতে পারে। 34 | 35 | ```js 36 | Rectangle.prototype.area = function () { 37 | return this.width * this.height; 38 | }; 39 | ``` 40 | 41 | এখন আমরা ইচ্ছে করলেই `Rectangle` Object এর `area` মেথডটি ব্যবহার করতে পারি। 42 | 43 | ```js 44 | var rect = new Rectangle(3, 4); 45 | rect.area(); // 12 46 | ``` 47 | 48 | আশা করি এই পর্যন্ত বুঝতে আমাদের কোন সমস্যা হয়ে নি। চলুন আমরা `square constructor` এর মাধ্যমে একটি Object তৈরি করি। 49 | 50 | ```js 51 | function Square(length) { 52 | this.width = this.height = length; 53 | } 54 | ``` 55 | 56 | আমরা সবাই জানি যে, Square আসলে একটা বিশেষ ধরনের Rectangle। তাহলে Rectangle এর বৈশিষ্ট্যগুলোও Square এর মধ্যে থাকা উচিত। কিন্তু কি করে এই কাজটি করব? 57 | যদি আমাদের মনে থেকে থাকে তবে আমরা জানি যে, `Object.create()` দিয়ে আমারা একটি খালি বা Empty Object তৈরি করতে পারি। তাহলে একটা কাজ করলে কেমন হয়, Square এর prototype এর একটা Object তৈরি করি Reactangle এর prototype কে প্যারেন্ট ধরে। 58 | 59 | ```js 60 | Square.prototype = Object.create(Rectangle.prototype); 61 | ``` 62 | 63 | এখন Square এর prototype এর মধ্যে Rectangle.prototype এর বৈশিষ্ট্যগুলো চলে এসেছে। সুতরাং, Square এর সকল Instance এর Prototype এর মধ্যেও এই বৈশিষ্ট্যগুলো থাকবে। তাহলে চলুন দেখি সবকিছু ঠিকঠাক কাজ করছে কি না। 64 | 65 | ```js 66 | var square = new Square(4); 67 | square.area(); // 16 68 | ``` 69 | 70 | উপরের কোডটি যদি একটু লক্ষ্য করে দেখুন তবে থেখা যাবে যে, আমরা `square` নামে যে Object টি তৈরি করেছি তার মধ্যে `area` মেথডটি চলে এসেছে। এটাই আসলে Prototypical Inheritance। 71 | এখন আমরা যদি চাই, তবে square এর মধ্যে শুধুমাত্র তার নিজের কিছু মেথড বা প্রপার্টি যোগ করতে পারি। চলুন তাহলে করা যাক, 72 | 73 | ```js 74 | Square.prototype.diagonal = function () { 75 | return Math.sqrt(this.area() * 2); 76 | }; 77 | ``` 78 | 79 | শেষ করার আগে একটা বিষয় মাথায় রাখা জরুরী, তা হল একটি Object কখনও একাধিক Prototypes Inherit করতে পারে না। 80 | তাহলে এই ছিল আজকের আলোচনা। আশা করি Prototypical Inheritance বুঝতে আর কোন সমস্যা হবে না। পরবর্তীতে অন্য কোন বিষয় নিয়ে আবার আলোচনা হবে। 81 | 82 | হ্যাপি কোডিং। 83 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/example1.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | When we are putting a code block inside setTimeout() function, 4 | we're actually declaring that code to be asynchronous. JS will 5 | send that code to the setTimeout() web api and after that it will be added 6 | to the task queue/callback queue. The event loop will it's work from that point. 7 | */ 8 | } 9 | 10 | console.log("First console"); 11 | setTimeout(() => { 12 | console.log("First setTimeout"); 13 | }, 1000); 14 | console.log("Second console"); 15 | setTimeout(() => { 16 | console.log("Second setTimeout"); 17 | }, 0); 18 | 19 | { 20 | /* 21 | Output: 22 | First console 23 | Second console 24 | Second setTimeout 25 | First setTimeout 26 | */ 27 | } 28 | 29 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/example2.js: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | Promises are not added to the callback queue. Instead it gets added to 4 | the micro task queue which has a higher priority than the task queue. 5 | The tasks existing in the micro task queue get pushed to the call stack 6 | by the event loop first. 7 | */ 8 | } 9 | 10 | firstPromise = new Promise((resolve) => { 11 | resolve("First promise.") 12 | }); 13 | secondPromise = new Promise((resolve) => { 14 | resolve("Second promise.") 15 | }); 16 | console.log("First console.") 17 | setTimeout(() => console.log("First setTimeout."), 1000); 18 | setTimeout(() => console.log("Second setTimeout.")); 19 | firstPromise.then(response => console.log(response)); 20 | secondPromise.then(response => console.log(response)); 21 | 22 | { 23 | /* 24 | Output: 25 | First console. 26 | First promise. 27 | Second promise. 28 | Second setTimeout. 29 | First setTimeout. 30 | */ 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | Event though setTimeout has a delay of 0s and 3 | while loop has 5s delay, event loop will wait until 4 | the call stack is empty. 5 | The while loop keeps on running on the call stack until 5s has elapsed 6 | */ 7 | 8 | function myFunc (){ 9 | console.log('first') 10 | setTimeout(function hello(){ 11 | console.log('second') 12 | }, 0) 13 | runforNSceconds(5) 14 | console.log('third') 15 | } 16 | 17 | myFunc() 18 | 19 | function runforNSceconds(sec){ 20 | let start = Date.now(), now = start; 21 | while(now-start< (sec*1000)){ 22 | now = Date.now() 23 | } 24 | } 25 | 26 | /* 27 | Output: 28 | first 29 | third 30 | second 31 | */ -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/example4.js: -------------------------------------------------------------------------------- 1 | //JS Eventloop এর উদাহরণ দেখান হয়েছে একটা URL এ request পাঠিয়ে 2 | //এটা করা হয়েছে এজ্যাক্স Request এর মাধ্যমে, যেটা Asynchronous 3 | //live: https://jsfiddle.net/rijans/v17t6qhu/10/ 4 | 5 | 6 | function main(url){ 7 | console.log('Lets get URL Headers!'); 8 | setTimeout( function (){ 9 | 10 | //get headers of an URL 11 | let req = new XMLHttpRequest(); 12 | req.open('GET', url, false); 13 | req.send(null); 14 | let headers = req.getAllResponseHeaders().toLowerCase(); 15 | 16 | console.log(headers); 17 | }, 1000); 18 | 19 | console.log('Done!'); 20 | } 21 | 22 | main('https:://vivasofltd.com'); 23 | 24 | //এটার ফলাফল এমন: 25 | // "Let get URL Headers!" 26 | // "End!" 27 | // "content-encoding: gzip 28 | // content-type: text/html; charset=utf-8 29 | // date: thu, 13 jan 2022 17:54:06 gmt 30 | // server: nginx 31 | // vary: origin 32 | // x-request-id: 64624b39-d4ec-4d4d-b8c4-480ddabc8709 33 | // x-runtime: 0.002067 34 | // " 35 | 36 | //লক্ষ করে দেখুন যে header response টা পরে আসছে, event লুপ এর কারণে 37 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Examples/example5.js: -------------------------------------------------------------------------------- 1 | //JS Eventloop এর উদাহরণ দেখান হয়েছে, নাম্বার counting এর মাধ্যমে। 2 | //live: https://jsfiddle.net/rijans/pkb3tsLg/ 3 | 4 | 5 | function main(number) { 6 | console.log('Lets count from 0 to ' + number); 7 | for (var i = 0; i <= number; i++) { 8 | setTimeout(function () { 9 | console.log(i + '\n'); 10 | }, 1000); 11 | } 12 | console.log('Done!'); 13 | } 14 | 15 | main(5); 16 | 17 | //এখানে output হবে এমন: 18 | // "Lets count from 0 to 5" 19 | // "Done!" 20 | // "6 21 | // " 22 | // "6 23 | // " 24 | // "6 25 | // " 26 | // "6 27 | // " 28 | // "6 29 | // " 30 | // "6 31 | // " 32 | 33 | //এটা ভার ভারিয়াবল এবং event-loop এর কারণে হয়েছে। এখানে লেট ভারিয়াবল ব্যাবহার করলে থিক ফল আসবে। 34 | 35 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/6. event-loop/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | What will be the output of this code snippet? 2 | 3 | 4 | ```javascript 5 | promise = new Promise((resolve) => { 6 | resolve("Promise."); 7 | }); 8 | 9 | setTimeout(() => console.log("First setTimeout."), 0); 10 | 11 | promise.then((res) => { 12 | setTimeout(() => console.log(res), 0); 13 | }); 14 | 15 | setTimeout(() => console.log("Second setTimeout."),0); 16 | console.log("First console."); 17 | ``` -------------------------------------------------------------------------------- /advanced/6. event-loop/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | We know event loop has different priorities when 3 | it comes to promise and setTimeout. Then what 4 | will be the output of this code? 5 | 6 | ```javascript 7 | setTimeout(function(){ 8 | console.log("first message") 9 | setTimeout(function(){ 10 | console.log("second message") 11 | }, 1000) 12 | }, 0) 13 | runforNSceconds(3) 14 | console.log("third message") 15 | 16 | let promise = new Promise(function(resolve, reject){ 17 | resolve() 18 | }) 19 | 20 | promise.then(function(resolve){ 21 | console.log("fourth message from promise 1") 22 | }) 23 | .then(function(promise){ 24 | console.log("fifth message from promise 2") 25 | }) 26 | 27 | console.log("sixth message") 28 | 29 | function runforNSceconds(sec){ 30 | let start = Date.now(), now = start; 31 | while(now-start< (sec*1000)){ 32 | now = Date.now() 33 | } 34 | } 35 | ``` -------------------------------------------------------------------------------- /advanced/6. event-loop/Practices/practice3.md: -------------------------------------------------------------------------------- 1 | নিচের কোডটির output কি হবে? 2 | 3 | ````js 4 | function main(number) { 5 | console.log('Lets count from 0 to ' + number); 6 | for (var i = 0; i <= number; i++) { 7 | setTimeout(function () { 8 | console.log(i + '\n'); 9 | }, 1000); 10 | } 11 | console.log('Done!'); 12 | } 13 | 14 | main(3); 15 | ```` 16 | -------------------------------------------------------------------------------- /advanced/6. event-loop/README.md: -------------------------------------------------------------------------------- 1 | ### Event loop 2 | 3 | আজকে আমরা জাভাস্ক্রিপ্টের খুবই একটা গুরুত্বপূর্ণ বিষয় নিয়ে আলোচনা করব, তা হল Event Loop. জাভাস্ক্রিপ্ট প্রোগ্রামার বা ডেভেলপার হিসাবে Event Loop সম্পর্কে ধারণা থাকা অত্যন্ত জরুরী। তাই চেষ্টা করবো আজকে Event Loop নিয়ে একটু লেখতে। চলুন শুরু করা যাক। 4 | 5 | ### Event loop কি? 6 | 7 | Event loop জাভাস্ক্রিপ্টের একটি secret machenism যার মাধ্যমে জাভাস্ক্রিপ্ট single-threaded প্রোগ্রামিং ল্যাঙ্গুয়েজ হওয়া সত্ত্বেও বাহ্যিক ভাবে multi-threaded প্রোগ্রামিং ল্যাঙ্গুয়েজের মত কাজ করে। Event loop গভীরভাবে call stack কে পর্যবেক্ষণ করে এবং যদি call stack খালি বা empty থাকে তবে Event queue থেকে Task call stack এ পাঠায় execution সম্পন্ন করার জন্য। 8 | 9 | আমরা সকলে জানি, জাভাস্ক্রিপ্ট একটি single-threaded asynchronous প্রোগ্রামিং ল্যাঙ্গুয়েজ । এইটা বিষয় লক্ষ্য করেছেন কি, একটা ল্যাঙ্গুয়েজ কি করে একই সাথে single-threaded আবার asynchronous হতে পারে? আসলে বিষয়টা হল, জাভাস্ক্রিপ্ট একটা single-threaded ল্যাঙ্গুয়েজ; তার মানে হল জাভাস্ক্রিপ্ট একসাথে একই সময়ে একটা মাত্র কাজ ে করতে পারে। আর asynchronous বিষয়টা জাভাস্ক্রিপ্ট ল্যাঙ্গুয়েজের কোন বিষয় না, এটি নিয়ন্ত্রিত হয় ব্রাউজার Enviornment এর মাধ্যমে। কয়েকটি উদাহরন দেখলে বিষয়টা বোঝতে সুবিধা হবে। 10 | চলুন শুরু করা যাক। 11 | 12 | ```js 13 | function main() { 14 | console.log('Hi'); 15 | setTimeout(function display() { 16 | console.log('there'); 17 | }, 1000); 18 | console.log('JSConfEU'); 19 | } 20 | main(); 21 | // Output 22 | // A 23 | // C 24 | // B 25 | ``` 26 | 27 | উপরের কোডটি একটু ভাল করে লক্ষ্য করুন, এখানে প্রথম `console.log('Hi')` এই Statement টি execute হচ্ছে। এরপর একটা setTimeout ফাংশন রয়েছে, যা নিদিষ্ট সময় পর `console.log('there')` এই Statement টি execute করার কথা ছিল। কিন্তু কোন কারণে এই Statement টিকে বাদ দিয়ে তারপরের Statement `console.log('JSConfEU')` এইটিকে execute করছে। এইটির কারণ হল জাভাস্ক্রিপ্টের asynchronous ব্যবহার। জাভাস্ক্রিপ্ট যখনই setTimeout ফাংশনটিকে দেখছে, ঠিক তখনই জাভাস্ক্রিপ্ট বোঝতে পারছে এটি একটি asynchronous ফাংশন । আর আমরা জানি asynchronous ফাংশনের কাজ শেষ হতে কিছু সময়ের প্রয়োজন হয়। তাই জাভাস্ক্রিপ্ট setTimeout ফাংশনটিকে আর `call stack` এ না রেখে, `Browser API` এ পাঠিয়ে দেয়। আর এই `Browser API` তেই setTimeout ফাংশনটি তার নির্ধারিত সময় নিয়ে কাজ টি শেষ করে। কাজ শেষ হবার পর setTimeout ফাংশনটি `Event Queue` তে প্রবেশ করে। এবং পুনরায় `call stack` এ প্রবেশ করার অপেক্ষা করে। 28 | ঠিক এখানে এ `Event Loop` এর কাজ শুরু হয়। `Event Loop` এর কাজ হল Call Stack আর Event Queue এর দিকে লক্ষ্য রাখা। যখন Call Stack খালি হয়ে যায় ঠিক তখন `Event Loop` Event Queue থেকে একটি একটি করে Event call stack এ পাঠায়। এবং call stack ওই অনুযায়ী Statement Execute করতে থাকে। এই প্রোগ্রামের ক্ষেত্রে `console.log('there')`statement টি Execute হয়। 29 | আর যখন setTimeout ফাংশনটিকে যখন call stack থেকে `Browser API` তে পাঠানো হয় তখন call stack টি খালি থাকার কারণে জাভাস্ক্রিপ্ট `console.log('JSConfEU')` statement টিকে call stack এ পাঠিয়ে execute করে ফেলে যার কারণে ``console.log('JSConfEU')` statement টি console.log('there') এর আগে execute করছে। 30 | 31 | জাভাস্ক্রিপ্টে setTimeout ছাড়া আরও কিছু ফাংশন আছে যা asynchronous API রয়েছে। যেমনঃ `addEventListener`, `setTimeout`, `setInterval`, যেকোনো ধরনের API কল। 32 | 33 | নিচের Graphical Representation টা দেখলে বিষয়টি আরও পরিষ্কার হবে। 34 | 35 | ![queue-example-jsconf (1)](https://user-images.githubusercontent.com/9677372/144177972-e998b3cf-7b37-4d52-9feb-f7926ffb9eeb.gif) 36 | 37 | এই ছিল আজকের আলোচনা। পরবর্তীতে অন্য কোন বিষয় নিয়ে আবার কথা হবে। হ্যাপি কোডিং। 38 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example1.js: -------------------------------------------------------------------------------- 1 | const person = { 2 | name: 'Anik', 3 | age: 25 4 | }; 5 | 6 | person = 'Anik'; 7 | 8 | // Initially, the person object is holding a bunch of internal attributes. 9 | // Then let’s assume I decided that a person could simply be represented 10 | // as a string. So now, the first person object has no references pointing 11 | // to it anymore, which makes it available for garbage collection. 12 | 13 | function circularObj() { 14 | var a = { }; 15 | var b = { }; 16 | 17 | a.prop = b; 18 | b.prop = a; 19 | }; 20 | 21 | circularObj(); 22 | 23 | // This creates a cycle. Once the function’s finished, JavaScript’s 24 | // reference-counting algorithm won’t be able to interpret that these two objects 25 | // can be collected because they still hold references to each other. 26 | // The 'Mark and sweep algorithm' can easily solve this problem. 27 | 28 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example2.js: -------------------------------------------------------------------------------- 1 | // 'Reference counting garbage collection' example: 2 | 3 | var object_1 = { 4 | object_2: { 5 | object_3: 7 6 | } 7 | }; 8 | 9 | // In the code above, two objects have been created. One of them is referred by another 10 | // as one of its properties. Currently, none can be garbage collected with the reference 11 | // counting algorithm. 12 | 13 | var object_4 = object_1; 14 | 15 | // Now the "object_4" variable is the second thing that has a reference to the object. 16 | // The objects that were originally in "object_1" has a unique reference embodied 17 | // by the "object_4" variable. 18 | 19 | object_1 = "Object 1"; 20 | 21 | var object_5 = object_4.object_2; 22 | // Reference to "object_2" property of the object. This object now has 2 references: 23 | // first one as a property, the other as the "object_5" variable. 24 | 25 | object_4 = "Object 4"; 26 | 27 | // The object that was in "object_1" has now zero references to it. It can be 28 | // garbage collected. However its "object_2" property is still referenced by the 29 | // "object_5" variable, so it cannot be freed. 30 | 31 | object_5 = null; 32 | 33 | // Now the "object_2" property has no references to it and so it can be garbage collected. -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | Here x is not in the scope anymore but we can 3 | still access it by using 'arr' array. That means it stays 4 | in the memory untill the reference is there. 5 | 6 | If we pop it from the array, it won't be needed anymore and can be garbage collected. 7 | */ 8 | 9 | let arr = [] 10 | function addName() { 11 | let x = {name: "Mehedi"} 12 | arr.push(x) 13 | } 14 | addName() 15 | console.log(arr[0]) // Output: { name: 'Mehedi' } 16 | arr = null; 17 | console.log(arr) // Output: null 18 | 19 | // Now the reference to properties of 'x' is null 20 | // So it is garbage collected 21 | 22 | 23 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example4.js: -------------------------------------------------------------------------------- 1 | /* 2 | We know that for interlinked/circular objects Reference Counting Algorithm doesn't work. 3 | Here in this example we will see how we can manually make 4 | interlinked object garbage collectable. 5 | */ 6 | 7 | function marry(man, woman) { 8 | woman.husband = man; 9 | man.wife = woman; 10 | 11 | return { 12 | father: man, 13 | mother: woman 14 | } 15 | } 16 | 17 | let family = marry({ 18 | name: "David" 19 | }, { 20 | name: "Angela" 21 | } 22 | ) 23 | 24 | /* 25 | Function marry links two objects by giving them references 26 | to each other and returns a new object that contains them both. 27 | Now all objects are reachable 28 | */ 29 | 30 | console.log(family.father) 31 | 32 | /* 33 | Suppose we want to make "David" unreachable/garbage collected, for that 34 | we need to remove all the references of "David" 35 | */ 36 | 37 | family.father = null; 38 | family.mother.husband = null; 39 | 40 | // Now all the references to "David" are gone. So it can be garbage collected -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example5.js: -------------------------------------------------------------------------------- 1 | let user = { 2 | name: 'Vivasoft', 3 | phone: '017' 4 | }; 5 | 6 | user = 'Vivasoft'; 7 | 8 | //জখন আমরা ইউজার ভারিয়াবল কে re-assign করলাম, JS দেখল আগের object আর ব্যাবহার হচ্ছেনা 9 | //তাই আগের object তাকে garbage হিসাবে মনে করবে 10 | 11 | function createUser() { 12 | var user1 = { }; 13 | var user2 = { }; 14 | 15 | user1.prop = user2; 16 | user2.prop = user1; 17 | }; 18 | 19 | createUser(); 20 | 21 | 22 | //যেহেতু user1 এবং user2 এখনো আগের সম্পর্ক বজায়ে রেখেছে, সেহেতু তাদেরকে reference-counting দিয়ে মুছা যাবেনা। 23 | //এখানে "Mark and Sweep Algorithm" টা ব্যাবহার করতে হবে। 24 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Examples/example6.js: -------------------------------------------------------------------------------- 1 | 2 | let list = []; 3 | function addToList() { 4 | list.push({name: "Jaber"}) 5 | } 6 | addToList() 7 | 8 | console.log(list[0]) 9 | // Output: { name: 'Jaber' } 10 | 11 | list = null; 12 | console.log(list) // Output: null 13 | 14 | //এখন রেফেরেঞ্চ function একটি garbage 15 | 16 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | Consider the following scenario. Will the 'Reference counting algorithm' be able to recognize these 2 objects as garbage? Between the two garbage collection algorithms of JS, which one will be more appropriate here and why? 2 | 3 | ```javascript 4 | function circularReference() { 5 | var one = {}; 6 | var two = {}; 7 | 8 | one.object = two; 9 | two.object = one; 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | Consider the code below. Why 'orange' object can still access 3 | all the property even though 'fruit' is deleted? 4 | 5 | ```javascript 6 | let fruit = { 7 | name: "Mango", 8 | price: 200, 9 | extra: { 10 | weight: "2 kg", 11 | color: "red" 12 | } 13 | } 14 | 15 | let orange = fruit; 16 | let mango = fruit.extra; 17 | 18 | fruit = null; 19 | mango = null; 20 | console.log(orange.name) 21 | ``` -------------------------------------------------------------------------------- /advanced/7. garbage-collector/Practices/practice3.md: -------------------------------------------------------------------------------- 1 | নিচের কোডটিতে কোন garbage collection algorithm কাজ করতে পারে? 2 | 3 | ````js 4 | let list = []; 5 | function addToList() { 6 | list.push({name: "Jaber"}) 7 | } 8 | addToList() 9 | 10 | console.log(list[0]) 11 | // Output: { name: 'Jaber' } 12 | 13 | list = null; 14 | console.log(list) // Output: null 15 | ```` -------------------------------------------------------------------------------- /advanced/README.md: -------------------------------------------------------------------------------- 1 | ## Table of contents 2 | 3 | 1. [Call, Apply, and Bind methods (কল, এপ্লাই এবং বাইন্ড মেথডস)](1.%20call-apply-bind-methods) 4 | 2. [Factory Pattern (ফ্যাক্টরি প্যাটার্ন)](2.%20factory-pattern) 5 | 3. [Constructor Pattern (কন্সট্রাক্টর প্যাটার্ন)](3.%20constructor-pattern) 6 | 4. [Prototype (প্রোটোটাইপ)](4.%20prototype) 7 | 5. [Prototypical Inheritance (প্রোটোটাইপিক্যাল ইনহেরিটেন্স)](5.%20prototypical-inheritance) 8 | 6. [Event Loop (ইভেন্ট লুপ)](6.%20event-loop) 9 | 7. [Garbage Collector (গার্বেজ কালেক্টর)](7.%20garbage-collector) 10 | -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example1.js: -------------------------------------------------------------------------------- 1 | 2 | {/* 3 | There are three types of Execution Context in javascript. 4 | 1.Global Execution Context(GEC) 5 | 2.Functional Execution Context(FEC) 6 | 3.Eval Execution Context 7 | 8 | Any JS code that gets executed within the eval function creates 9 | and holds its own execution context. However, 10 | the eval function is not used by the JavaScript developers, 11 | but it is a part of the Execution Context. 12 | 13 | 14 | At first the program will execute inside the 15 | global execution context. But if the program call a function 16 | then it will creates a new functional execution context. 17 | When function return anything then the FEC will be removed from call stack 18 | and returned value will be pass into the GEC again 19 | the 20 | */} 21 | 22 | let x = 10; 23 | 24 | function timesTen(a){ 25 | return a * 10; 26 | } 27 | 28 | let y = timesTen(x); 29 | 30 | console.log(y); 31 | 32 | {/* 33 | output: 34 | 100 35 | 36 | */} 37 | 38 | -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example2.js: -------------------------------------------------------------------------------- 1 | {/* 2 | 3 | Time Tide and Javascript waits for none. 4 | The function fn has an asynchrous function setTimeout 5 | with a timer of 5 sec. As we know javascript has only a call stack 6 | to execute all code, so it never waits for the timeout. 7 | Js engine will send the function to the dom api 8 | and move on to the next line of code 9 | */} 10 | 11 | console.log('first output of global execution context') 12 | 13 | function fn(){ 14 | console.log('waiting for timeout...') 15 | setTimeout(()=>{ 16 | console.log('Output in Functions local execution contex') 17 | },5000) 18 | } 19 | 20 | fn() 21 | console.log('last output of global execution context') 22 | 23 | {/* 24 | output: 25 | first output of global execution context 26 | waiting for timeout... 27 | last output of global execution context 28 | Output in Functions local execution contex 29 | 30 | ie:Time and Js wait for none 31 | */} -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example3.js: -------------------------------------------------------------------------------- 1 | {/* 2 | Here we store the return value for 3 | average(10, 20) in variable x within the global execution context. 4 | So when the average function called, a functional execution 5 | context will creates for function average inside the call stack. 6 | Inside average we call function add. so Another functional 7 | execution context will create for add function in the call stack. 8 | When the add function return anything then the 9 | functional execution context will be removed from the call stack 10 | and the return value will be returned to the functional execution 11 | context of average from where the function add was called. 12 | Again when average function return anything then 13 | its functional execution context will also removed from 14 | the call stack and the return value will also returned th 15 | the global execution context from where the average function was called 16 | 17 | 18 | */} 19 | 20 | function add(a, b) { 21 | return a + b; 22 | } 23 | 24 | function average(a, b) { 25 | return add(a, b) / 2; 26 | } 27 | 28 | let x = average(10, 20); 29 | console.log(x) 30 | 31 | {/* 32 | output: 33 | 15 34 | */} -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example4.js: -------------------------------------------------------------------------------- 1 | 2 | {/* 3 | Time Tide and Javascript waits for none. 4 | The function fn has an asynchrous function setTimeout 5 | with a timer of 5 sec. As we know javascript has only a call stack 6 | to execute all code, so it never waits for the timeout. 7 | Js engine will send the function to the dom api 8 | and move on to the next line of code 9 | */} 10 | 11 | 12 | onsole.log('First Output Inside the Global Execution context') 13 | 14 | function fn1(){ 15 | setTimeout(()=>{ 16 | console.log('Inside function fn1 with the SetTimeout of 3 seconds') 17 | },3000) 18 | } 19 | 20 | function fn2(){ 21 | console.log('inside function fn2') 22 | } 23 | 24 | setTimeout(()=>{ 25 | console.log('Inside the Global Execution context With SetTimeout of 10 seconds') 26 | },10000) 27 | 28 | setTimeout(()=>{ 29 | console.log('Inside the Global Execution context With SetTimeout of 3 seconds') 30 | },3000) 31 | 32 | fn1() 33 | fn2() 34 | fn3() 35 | 36 | function fn3(){ 37 | console.log('Inside function fn3') 38 | } 39 | 40 | console.log('Last line Output of Global Execution Context') 41 | 42 | 43 | {/* 44 | 45 | output: 46 | First Output Inside the Global Execution context 47 | inside function fn2 48 | Inside function fn3 49 | Last line Output of Global Execution Context 50 | Inside the Global Execution context With SetTimeout of 3 seconds 51 | Inside function fn1 with the SetTimeout of 3 seconds 52 | Inside the Global Execution context With SetTimeout of 10 seconds 53 | */} -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example5.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Global Execution Context 4 | GEC / Global Execution Context is also called 5 | the base/default execution. Any JavaScript 6 | code which does not reside in any function 7 | will be present in the global execution context. 8 | The reason behind its name 'default execution 9 | context' where the code begins its execution 10 | when the file first loads in the web browser. 11 | GEC performs the two following tasks: 12 | 13 | Firstly, it creates a global object where it is 14 | for Node.js and Window object for the browsers. 15 | Secondly, reference the Windows object to 'this' keyword. 16 | Create a memory heap in order to store variables and function references. 17 | Then it stores all the functions declarations in the memory 18 | heap area and the variables in the GEC with initial values as 'undefined'. 19 | 20 | Function statement is hoisted , so we can called a function statent before the 21 | declarations 22 | 23 | */ 24 | } 25 | 26 | let globalVar = "Variable from Global skope"; 27 | 28 | function a() { 29 | console.log("Inside a"); 30 | console.log(globalVar); 31 | console.log(); 32 | let x = "functional skope of function a"; 33 | b(); 34 | 35 | function b() { 36 | console.log("Inside b"); 37 | let y = "functional skope of function b"; 38 | console.log(globalVar); 39 | console.log(x); 40 | console.log(); 41 | c(); 42 | 43 | function c() { 44 | console.log("Inside c"); 45 | let y = "functional skope of function b"; 46 | console.log("value of x : ", x); 47 | console.log(globalVar); 48 | console.log(y); 49 | var x = "functional skope of function c"; 50 | console.log("value of x : ", x); 51 | } 52 | } 53 | } 54 | a(); 55 | 56 | { 57 | /* 58 | 59 | output: 60 | Inside a 61 | Variable from Global skope 62 | Inside b 63 | Variable from Global skope 64 | functional skope of function a 65 | Inside c 66 | value of x : undefined 67 | Variable from Global skope 68 | functional skope of function b 69 | value of x : functional skope of function c 70 | */ 71 | } 72 | -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/example6.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | এক্সিকিউশন স্ট্যাকের কাজের প্রক্রিয়াটি বোঝার জন্য, নীচে দেওয়া একটি উদাহরণ কোড বিবেচনা করুন: 4 | 5 | ব্যাখ্যা: 6 | * প্রথমত, সমস্ত কোড ব্রাউজারে লোড করা হয়। 7 | * এর পরে, JS ইঞ্জিন এক্সিকিউশন স্ট্যাকের শীর্ষে GEC push/insert করে। 8 | * যত তাড়াতাড়ি JS ইঞ্জিন প্রথম ফাংশন কলের সম্মুখীন হয়, এটি এটির জন্য একটি নতুন FEC সেট করে এবং এটি বর্তমান এক্সিকিউশন স্ট্যাকের শীর্ষে যোগ করে। 9 | * তারপর আমরা দেখতে পারি যে এটি প্রথম ফাংশনের মধ্যে দ্বিতীয় ফাংশনের Call। অতএব JS ইঞ্জিন দ্বিতীয় ফাংশনের জন্য একটি নতুন FEC সেটআপ করে এবং এটি স্ট্যাকের শীর্ষে যোগ করে। 10 | * যখন দ্বিতীয় ফাংশন সম্পন্ন হয়, এক্সিকিউশন ফাংশনটি স্ট্যাকের বাইরে চলে যায় এবং নিয়ন্ত্রণগুলি স্ট্যাকের মধ্যে উপস্থিত পরবর্তী এক্সিকিউশন প্রসঙ্গে চলে যায়, যা শুধুমাত্র প্রথম ফাংশন এক্সিকিউশন প্রসঙ্গ। 11 | * যখন প্রথম ফাংশনটি সম্পূর্ণভাবে সম্পন্ন হয়, তখন প্রথম ফাংশনের এক্সিকিউশন স্ট্যাক, স্ট্যাক থেকে বেরিয়ে আসে। অতএব, নিয়ন্ত্রণটি কোডের GECতে ফিরে আসে। 12 | * শেষ পর্যন্ত, যখন সম্পূর্ণ কোডের এক্সিকিউশন সম্পন্ন হয়, JS ইঞ্জিন GEC কে বর্তমান স্ট্যাক থেকে সরিয়ে দেয়। 13 | 14 | */ 15 | 16 | let x = "Hello Execution context!"; 17 | 18 | function a() { 19 | console.log("This is the first function execution"); 20 | 21 | function b() { 22 | console.log("This is the second function execution"); 23 | } 24 | 25 | b(); 26 | } 27 | 28 | a(); 29 | 30 | console.log("It is GEC. " + x); 31 | 32 | /* 33 | Output: 34 | 35 | This is the first function execution 36 | This is the second function execution 37 | It is GEC. Hello Execution context! 38 | */ -------------------------------------------------------------------------------- /basic/1. execution-context/Examples/stackOverflow.js: -------------------------------------------------------------------------------- 1 | {/* 2 | Here foo function called itself again and again. 3 | So the call stack will store the same copy of foo for 4 | each function call And a functional execution context 5 | will create for every call inside the call stack. 6 | These cause the stack overflow. Because Call stack 7 | also has an specific memory limit 8 | */} 9 | function foo() { 10 | foo(); 11 | } 12 | 13 | foo(); 14 | 15 | {/* 16 | Uncaught RangeError: Maximum call stack size exceeded 17 | at foo (:2:5) 18 | at foo (:2:5) 19 | at foo (:2:5) 20 | at foo (:2:5) 21 | at foo (:2:5) 22 | at foo (:2:5) 23 | at foo (:2:5) 24 | at foo (:2:5) 25 | at foo (:2:5) 26 | at foo (:2:5) 27 | */} -------------------------------------------------------------------------------- /basic/1. execution-context/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/1. execution-context/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/1. execution-context/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | নিচের কোড দেখুন। ভেরিয়েবল a এর মান check() ফাংশনের মধ্যে পরিবর্তন করা কি সম্ভব? check() ফাংশনের বাইরে ভেরিয়েবল b কে একসেস করা কি সম্ভব? এক্সিকিউশন কন্টেক্সট এর উপর ভিত্তি করে হ্যাঁ অথবা না উভয় ক্ষেত্রে আপনার যুক্তি ব্যাখ্যা করুন। 3 | 4 | ```javascript 5 | 6 | let a = 12; 7 | 8 | function check() { 9 | let b = 23; 10 | a = 44; // Will it change the value of the variable a? 11 | } 12 | 13 | console.log(a); 14 | check(); 15 | console.log(a); 16 | b = 55; // Is it possible? 17 | 18 | ``` 19 | 20 | 21 | একটি প্রোগ্রামে কয়টি গ্লোবাল এক্সিকিউশন কন্টেক্সট ও কয়টি ফাংশনাল এক্সিকিউশন কন্টেক্সট থাকতে পারে? নীচের প্রোগ্রামটি রান করলে কয়টি গ্লোবাল ও ফাংশনাল এক্সিকিউশন কন্টেক্সট তৈরী করবে? 22 | 23 | ```javascript 24 | 25 | function a() { 26 | console.log('Function a() executed'); 27 | 28 | function b() { 29 | console.log('Function b() executed'); 30 | } 31 | 32 | function c() { 33 | console.log('Function c() executed'); 34 | 35 | function cc() { 36 | console.log('Function cc() executed'); 37 | } 38 | } 39 | } 40 | 41 | function d() { 42 | console.log('Function d() executed'); 43 | 44 | function e() { 45 | console.log('Function e() executed'); 46 | 47 | function ee() { 48 | console.log('Function ee() executed'); 49 | } 50 | } 51 | 52 | e(); 53 | } 54 | 55 | a(); 56 | d(); 57 | 58 | ``` -------------------------------------------------------------------------------- /basic/1. execution-context/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | 2 | ```JavaScript 3 | let num = 5; 4 | 5 | const changeNum = () => { 6 | let num; 7 | num = 72; 8 | console.log(num); 9 | } 10 | 11 | changeNum(); 12 | console.log(num); 13 | ``` 14 | 15 | উপরের কোডের আউটপুট কি হবে? যদি changeNum() ফাংশনের ভেতরে গ্লোবাল ভ্যারিয়েবল num -এর মান পরিবর্তন না হয় তাহলে আমরা কিভাবে সেটা করতে পারবো? -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Examples/example1.js: -------------------------------------------------------------------------------- 1 | /* 2 | In this example, we will learn about localStorage of a browser. 3 | As we already know, in localStorage the data is persisted until 4 | the user manually clears the browser cache or until your web app clears the data. 5 | */ 6 | 7 | // To create a entity we need to use a function named setItem 8 | // which takes key and value as parameters 9 | 10 | localStorage.setItem("item1", "Football") 11 | 12 | // we can read this by using getItem 13 | localStorage.getItem("item1") 14 | 15 | // we can also update the existing item by using setItem 16 | localStorage.setItem("item1", "Cricket") 17 | 18 | // we can delete the item using removeItem 19 | localStorage.removeItem("item1") 20 | 21 | // we can also clear everything that stored in localStorage by using this 22 | localStorage.clear() 23 | 24 | /* 25 | We can also use these 4 methods in sessionStorage. like, 26 | sessionStorage.setItem(), sessionStorage.getItem(), sessionStorage.removeItem() and 27 | sessionStorage.clear() 28 | */ -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Examples/example2.js: -------------------------------------------------------------------------------- 1 | /* 2 | Only strings can be stored with localStorage or sessionStorage, 3 | but we can use JSON.stringify to store more complex objects. 4 | */ 5 | 6 | // Create item 7 | let person = {name: "mehedi", designation: "Front End Developer"} 8 | localStorage.setItem("person1", JSON.stringify(person)) 9 | 10 | // Read item 11 | let item = JSON.parse(localStorage.getItem("person1")) -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/10. browser-storage-and-caching/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | Consider the object below. Suppose we want to store this object 3 | in the localStorage and sessionStorage of our browser. How can we do that? 4 | Also how can you can read this object from the localStorage and sessionStorage? 5 | 6 | ```javascript 7 | let team = { 8 | name: "Real Madrid", 9 | ucl: 13, 10 | laliga: 33 11 | } 12 | ``` -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Examples/example1.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | Throttling 14 | 15 | 16 | 17 | 37 | 38 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Examples/example2.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | Debouncing Example 11 | 12 | 13 | 14 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | Consider this scenario. If someone moves his mouse on the map, 3 | we are displaying the location coordinates of the mouse pointer. 4 | In this scenario, which formula we should use? Debouncing or Throttling? 5 | -------------------------------------------------------------------------------- /basic/11. debouncing-and-throttling/README.md: -------------------------------------------------------------------------------- 1 | ### Debouncing and Throttling 2 | 3 | আমাদের আজকের আলোচনার বিষয় হল জাভাস্ক্রিপ্টের Debouncing এবং Throttling. জাভাস্ক্রিপ্টের কোন Application কে অপ্টিমাইজ করার জন্য বা ব্রাউজার Performance কে আরও উন্নত করার জন্য Debouncing এবং Throttling ব্যবহার করা হয়। তাহলে চলুন আলোচনা শুরু করা যাক। 4 | 5 | ### Debounce ফাংশন কি? 6 | 7 | Debounce ফাংশন হল এমন একটি ফাংশন যা কোন ফাংশন কতবার কল হবে তা নিয়ন্ত্রণ করে এবং কিছু নিদিষ্ট সময় অপেক্ষা করার পর পুনরায় ওই ফাংশনটিকে কল করে। চলুন একটা উদাহরন দেখা যাক। 8 | 9 | বেশিরভাগ ওয়েবসাইটেই Search Bar থাকে যার মাধ্যমে User কিছু Specific Keyword দিয়ে সার্চ করে কাঙ্খিত ফলাফল পেয়ে থাকে। Ecommerce সাইটে User যখন কোন প্রোডাক্টের নাম দিয়ে সার্চ করে তখন ওই টাইপের যত প্রোডাক্ট আছে তা User এর কাছে চলে আসে। সুতরাং এখানে যা হচ্ছে তা হলো, User যখন কোন একটা সার্চ Query লিখে তখন সার্চ Query এর প্রত্যেকটা Character এর জন্য API কল হয়। উদাহরণস্বরূপ, User যদি "Apple Macbook Pro" লিখে সার্চ করে তবে ১৭ বার API call হবে এই সার্চের ফলাফল দেখানোর জন্য। এটা কখনও একটা ভাল Approach হতে পারে না। আমরা এখানে Debounce ব্যবহার করে API call এর পরিমাণ কমিয়ে অনেক Optimization করতে পারি। 10 | 11 | চলুন, আমাদের প্রথম debounce ছাড়া আমাদের কোডটা কেমন হবে তা দেখি। 12 | 13 | ```html 14 | 15 | ``` 16 | 17 | আমরা সাধারণত Search Functionality গুলো onChange অথবা onKeyUp ইভেন্টের মাধ্যমে করে থাকি। এখন আমরা আমারদের `searchHandler` ফাংশনটা লিখে ফেলি। 18 | 19 | ```js 20 | function searchHandler(...args) { 21 | /* Here we are capturing the search query entered by customer */ 22 | const { value } = args[0].target; 23 | /* Make an API call with search query */ 24 | getSearchResults(value); 25 | } 26 | ``` 27 | 28 | আশা করছি এই পর্যন্ত বুঝতে কোন সমস্যা হচ্ছে না। তাহলে চলুন আমরা একটা reusable Debounce ফাংশন লিখে ফেলি। 29 | 30 | ```js 31 | const optimisedSearchHandler = debounceFunc(searchHandler, 500); 32 | const debounceFunc = (func, delay) => { 33 | let timer; 34 | return function (...args) { 35 | const context = this; 36 | clearTimeOut(timer); 37 | timer = setTimeOut(() => { 38 | func.apply(context, args); 39 | }, delay); 40 | }; 41 | }; 42 | ``` 43 | 44 | উপরের কোডটা একটু লক্ষ্য করে দেখুন, যখন আমরা সার্চবার এ কিছু লিখার সাথে সাথে এ API কল করছে না। এটি আমাদের সার্চবার এ কিছু লিখার পর একটা নিদিষ্ট সময় অপেক্ষা করছে যদি এর মধ্যে সার্চবার এ আর নতুন কিছু টাইপ করা না হয় তবেই এটি API কে কল করছে। এতে করে আমাদের API কল এর পরিমাণ অনেকখানি কমে গেল। 45 | তাহলে চলুন, আমরা আমাদের সার্চবারের `onChange` debounce Technique টা ব্যবহার করে ফেলি। 46 | 47 | ```html 48 | 49 | ``` 50 | 51 | চলুন, এবার `Throttling` নিয়ে আলোচনা করা যাক। 52 | 53 | ### Throttling 54 | 55 | ### Throttling আসলে কি? 56 | 57 | Throttling এমন একটি Technique যার মাধ্যমে Event Handler এর অ্যাকশানকে Limited করা যায়। অর্থাৎ একটা Event কল হবার পর সুনিদিষ্ট টাইম এর মধ্যে ওই Event আর কল হবে না। বুঝার সুবিধার জন্য আমরা একটা উদাহরনস্বরূপ শুটিংগেমের কথা চিন্তা করতে পারি। একটি শুটিং গেমে বেশ কয়েক ধরনের অস্ত্র থাকতে পারে। প্রতিটি অস্ত্রেরই একটি Fire এর পর পরবর্তী Fire এর জন্য প্রস্তুত হতে কিছু টাইম লাগে। যেমন ShortGun এর ক্ষেত্রে যে সময় লাগবে MachineGun এর ক্ষেত্রে আরও কম সময় লাগবে। ধরি, shortGun এর জন্য এই সময় 500ms আর MachineGun এর জন্য এই টাইম 100ms. তাই আমাদের এমন একটা লজিক সেট করতে হবে যাতে করে User যে অস্ত্র ব্যবহার করুক না কেন, যদি সে Threshold টাইমের মধ্যে একাধিক বার Fire করে তবে শুধুমাত্র একটা Fireই কাজ করবে। আর Fire গুলো নিদিষ্ট সময়ের পর এক এক করে Fire করবে। 58 | 59 | চলুন তাহলে Trigger ক্লিকের একটা Event Handler তৈরি করে ফেলি। 60 | 61 | ```js 62 | window.addEventListener(onclick, handlerTrigger); 63 | const handlerTrigger = () => { 64 | fireShot(); 65 | }; 66 | ``` 67 | 68 | উপরের কোডটি লক্ষ্য করুন, User যখনই Trigger press করছে শট Fire হচ্ছে। 69 | তাহলে চলুন এখন আমরা Throttle ফাংশন লিখে ফেলি যার parameter এ `handlerTrigger` ফাংশন আর Time Interval কে পাঠাবো। 70 | 71 | ```js 72 | const optimisedTriggerHandler = throttleFunc(handlerTrigger, 100); 73 | const throttleFunc = (func, interval) => { 74 | let shouldFire = true; 75 | return function () { 76 | if (shouldFire) { 77 | func(); 78 | shouldFire = false; 79 | setTimeOut(() => { 80 | shouldFire = true; 81 | }, interval); 82 | } 83 | }; 84 | }; 85 | ``` 86 | 87 | তাহলে চলুন, এখন আমরা আমাদের Event Listener ফাংশনটি আপডেট করে ফেলি। 88 | 89 | ```js 90 | window.addEventListener(onclick, optimisedTriggerHandler); 91 | ``` 92 | 93 | ঠিক এইভাবে আমরা বিভিন্ন Time Interval সেট করে `optimisedTriggerHandler` কে বিভিন্ন অস্ত্রের জন্য ব্যবহার করতে পারি। 94 | 95 | আমরা এখন পর্যন্ত Debouncing and Throttling দুইটি Techniqueই দেখলাম। এই দুইটি পদ্ধতি concept খুব কাছাকাছি হলে মূল পার্থক্য হল, Debouncing এর ক্ষেত্রে User এর অ্যাকশান কে মনিটর করি এবং Threshold Time এর মধ্যে আবার যদি কোন নতুন অ্যাকশান আসে তবে আবার নতুন করে Threshold Time পর্যন্ত অপেক্ষা করি API কল এর জন্য। অন্যদিকে, Throttling এর ক্ষেত্রে আমরা আমাদের predetermined time interval পর API কল করে দেই। 96 | 97 | আশা করি, Debouncing and Throttling বুঝতে আর কোন সমস্যা হবার কথা না। পরবর্তীতে আবার নতুন কোন বিষয় নিয়ে আবার কথা হবে। সে পর্যন্ত হ্যাপি কোডিং। 98 | -------------------------------------------------------------------------------- /basic/12. use-strict/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/12. use-strict/Examples/example1.js: -------------------------------------------------------------------------------- 1 | // In this example we will see some usage of "strict mode". 2 | // As we already know, "use strict" defines that JavaScript code 3 | // should be executed in "strict mode", which is safer feature set of javascript. 4 | 5 | // if we declare "use strict" at the beginning of a script, it has global scope 6 | 7 | // Deleting a variable, function or object is not allowed in strict mode 8 | 9 | "use strict"; 10 | let x = 10; 11 | delete x; 12 | // Output: 13 | // SyntaxError: Delete of an unqualified identifier in strict mode. 14 | 15 | function myFunction(){ 16 | console.log("Hello") 17 | } 18 | delete myFunction; 19 | // Output: 20 | // SyntaxError: Delete of an unqualified identifier in strict mode. 21 | 22 | let person = { 23 | name: "Mehedi", 24 | age: 24 25 | } 26 | delete person; 27 | // Output: 28 | // SyntaxError: Delete of an unqualified identifier in strict mode. -------------------------------------------------------------------------------- /basic/12. use-strict/Examples/example2.js: -------------------------------------------------------------------------------- 1 | // Normally, we can use keywords such as eval, arguments as variable names 2 | // but using strict mode, we cannot do that 3 | "use strict" 4 | 5 | let eval = 10; 6 | console.log(eval) 7 | // Output: 8 | // SyntaxError: Unexpected eval or arguments in strict mode 9 | 10 | let arguments = 20; 11 | console.log(arguments) 12 | // Output: 13 | // SyntaxError: Unexpected eval or arguments in strict mode 14 | 15 | // Keywords reserved for future JavaScript versions also cant be used as variable names in strict mode. 16 | // Such as public, private, protected, static, interface, implements etc. -------------------------------------------------------------------------------- /basic/12. use-strict/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/12. use-strict/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/12. use-strict/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | Consider this code below. Will it give an error? 3 | 4 | ```javascript 5 | let name = "Mehedi"; 6 | 7 | function printName(name){ 8 | "use strict" 9 | console.log(name); 10 | let age = 24; 11 | delete age 12 | } 13 | ``` -------------------------------------------------------------------------------- /basic/12. use-strict/README.md: -------------------------------------------------------------------------------- 1 | প্রায় সব ল্যাংগুয়েজেরই নিজস্ব একটা ডকুমেন্ট আছে। যার মাধ্যমে আমরা ঐ ল্যাংগুয়েজের ভাল কিংবা খারাপ দিক অথবা ভাল প্র্যাকটিস এবং খারাপ প্র্যাকটিস সম্পর্কে জানতে পারি। কিন্তু জাভাস্ক্রিপ্টের এই রকম কোন কিছু নেই। যে কারণে এখানে ভুলটা বেশি হবার সুযোগ থাকে এবং সবাই নিজের মত করে কোড লিখে সে ভুলটা করেও বটে। যেগুলো আসলে ভুল সিনট্যাক্স এবং আনসিকিউর কোড। কিন্তু আমরা যখন স্ট্রিক্ট মোড ব্যবহার করি, তখন জাভাস্ক্রিপ্ট কোড কোন ভুল সিনট্যাক্স ছাড়া এক্সিকিউট করে এবং কোড আরও সিকিউর করে। 2 | 3 | ### “use strict” ডিরেক্টিভঃ- 4 | **“use strict”** মোডে আমাদের কোড এক্সিকিউট করতে হলে আমাদেরকে **“use strict”** ডিরেক্টিভ ব্যবহার করতে হবে। এটি একটি এক্সপ্রেশন মাত্র। এটি জাভাস্ক্রিপ্টের ১.৮.৫ (ইএস৫) থেকে সাপোর্ট করে। 5 | 6 | ### “use strict” এর ব্যবহারঃ- 7 | **“use strict”** ডিরেক্টিভকে আমরা দুইভাবে ব্যবহার করতে পারি। গ্লোবাল ডিক্লারেশন হিসাবে এবং ফাংশন ডিক্লারেশন হিসাবে। 8 | 9 | ### গ্লোবাল ডিক্লারেশনঃ- 10 | যখন আমরা গ্লোবাল ডিক্লারেশন হিসাবে **“use strict”** ব্যবহার করি, তখন ঐ পেজের সমস্ত জাভাস্ক্রিপ্ট কোড স্ট্রিক্ট মোডে এক্সিকিউট হয়। 11 | 12 | ```js 13 | "use strict"; 14 | 15 | console.log("Hello JavaScript"); 16 | ``` 17 | 18 | ### ফাংশন ডিক্লারেশনঃ- 19 | যখন আমরা ফাংশন ডিক্লারেশন হিসাবে **“use strict”** ব্যবহার করি, তখন ফাংশনের ভিতরের সমস্ত জাভাস্ক্রিপ্ট কোড স্ট্রিক্ট মোডে এক্সিকিউট হয়। ফাংশনের বাহিরে সব কোড নর্মাল মোডে এক্সিকিউট হয়। 20 | 21 | ```js 22 | (function() { 23 | "use strict"; 24 | 25 | console.log("Hello JavaScript"); 26 | })(); 27 | ``` 28 | 29 | ##### উদাহরন – ১ঃ 30 | আপনি জাভাস্ক্রিপ্টে ভেরিয়েবল কি-ওয়ার্ড ডিক্লেয়ার না করেও কাজ করতে পারবেন। কারণ আমরা জানি জাভাস্ক্রিপ্টে ভেরিয়েবলের নামের আগে ভেরিয়েবল কি-ওয়ার্ড ব্যবহার না করলে এটি বাই-ডিফল্ট উইন্ডো অবজেক্টের আন্ডারে এক্সিকিউট হয়। 31 | 32 | ```js 33 | num = 10; 34 | 35 | console.log(num); // 10 36 | ``` 37 | 38 | একই কোড যখন আমরা **“use strict”** ব্যবহার করে এক্সিকিউট করবো, আমরা একটা Uncaught ReferenceError: num is not defined পাবো। 39 | 40 | ```js 41 | "use strict"; 42 | 43 | num = 10; 44 | 45 | console.log(num); // Uncaught ReferenceError: num is not defined 46 | ``` 47 | 48 | #### উদাহরন-২ঃ 49 | 50 | জাভাস্ক্রিপ্টে আমরা রিজার্ভড কি-ওয়ার্ডগুলো ব্যবহার করতে পারি ভেরিয়েবলের নাম হিসাবে। 51 | 52 | ```js 53 | var let = 10; 54 | 55 | console.log(let); // 10 56 | ``` 57 | 58 | কিন্তু **“use strict”** মোডে এটি সম্ভব নয়। কারণ এটি ইএস৬ এর জন্যে একটি রিজার্ভড কি-ওয়ার্ড। 59 | 60 | ```js 61 | "use strict"; 62 | var let = 10; 63 | 64 | console.log(let); // Uncaught SyntaxError: Unexpected strict mode reserved word 65 | ``` 66 | 67 | ### কিছু রিজার্ভড কি-ওয়ার্ডঃ 68 | 69 | - abstract 70 | - instanceof 71 | - super 72 | - static 73 | - package 74 | - const 75 | - implements 76 | - with 77 | - private 78 | - protected 79 | 80 | #### উদাহরন – ৩ঃ 81 | ফাংশনের ভিতরে **“this”** এর ভ্যালু সব সময় উইন্ডো অবজেক্ট হয়। 82 | 83 | ```js 84 | function showMe() { 85 | console.log(this); 86 | } 87 | 88 | showMe(); /// window 89 | ``` 90 | কিন্তু **“use strict”** মোডে ফাংশনের ভিতরে **“this”** এর ভ্যালু **undefined** হবে। 91 | 92 | ```js 93 | "use strict"; 94 | 95 | function showMe() { 96 | console.log(this); // undefined 97 | } 98 | 99 | showMe(); /// window 100 | ``` 101 | 102 | এই রকম আরও অনেক ব্যবহারের ক্ষেত্র আছে যেটি আপনারা একটু কষ্ট করে নিজ দায়িত্বে দেখে নিবেন। যাইহোক, যেহেতু জাভাস্ক্রিপ্টের জন্যে নির্দিষ্ট কোন ডকুমেন্টস নেই, তাই **“use strict”** ব্যবহার করলে আমরা আমাদের কোডের ডিবাগ করতে সুবিধা হবে। কারণ যদি আমরা কোন ভুল সিনট্যাক্স ব্যবহার করি, জাভাস্ক্রিপ্ট আমাদেরকে ইরর থ্রো করবে। যেটি জাভাস্ক্রিপ্ট সাধরণত করে না। আশা করি, ব্যাপারটা সবাই বুঝতে পারছেন। আর পারবেনই বা কেন? সিম্পল হিসাব, জাভাস্ক্রিপ্ট জিন্দাবাদ। 😛 -------------------------------------------------------------------------------- /basic/13. iife-in-javascript/Examples/example1.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | IIFE follow their own scope like any other function/variable in JavaScript. 4 | It is confusing sometimes that we might expect the IIFE 5 | to execute irrespective of function scope, which is wrong. 6 | In this example where the IIFE is defined within a function 7 | and will only be immediately invoked if we call the Parent Function. 8 | 9 | */ 10 | 11 | function sayName() 12 | { 13 | console.log("Hello!"); 14 | // This will be executed after executing the previous log. 15 | (function() { console.log("Mehedi"); })(); 16 | console.log("is my name"); 17 | } 18 | 19 | // Calling the parent function. 20 | sayName(); 21 | /* 22 | Output: 23 | Hello! 24 | Mehedi 25 | is my name 26 | */ -------------------------------------------------------------------------------- /basic/13. iife-in-javascript/Examples/example2.js: -------------------------------------------------------------------------------- 1 | /* 2 | We can use IIFEs to create private variables and functions 3 | within the global scope, or any other function scope. 4 | */ 5 | 6 | function sayName(){ 7 | return "Hello! I am Mehedi"; 8 | } 9 | 10 | console.log(sayName()) 11 | 12 | var myNumber = 100; 13 | console.log(myNumber*2) 14 | 15 | /* 16 | If we load other JavaScript files in our browser, 17 | they also gain access to sayName() and myNumber. 18 | To prevent them from using or editing them, we encase our code in an IIFE like this code bolw: 19 | */ 20 | (function(){ 21 | function sayName(){ 22 | return "Hello! I am Mehedi"; 23 | } 24 | 25 | console.log(sayName()) 26 | 27 | var myNumber = 100; 28 | console.log(myNumber*2) 29 | })(); 30 | // It runs the same, but now sayName() and myNumber are only accessible in our script. 31 | -------------------------------------------------------------------------------- /basic/13. iife-in-javascript/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/13. iife-in-javascript/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/13. iife-in-javascript/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | Consider the code written below. 3 | What will be the output of this code? 4 | 5 | ```javascript 6 | function sayHello() 7 | { 8 | console.log("Hello!"); 9 | (function(){ 10 | console.log("Nice to meet you"); 11 | (function(){ 12 | console.log("I want to tell you") 13 | })(); 14 | })(); 15 | console.log("something you want to hear"); 16 | } 17 | 18 | // Calling the parent function. 19 | sayHello(); 20 | ``` -------------------------------------------------------------------------------- /basic/2. scope/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/2. scope/Examples/example1.js: -------------------------------------------------------------------------------- 1 | /* 2 | Function scope: 3 | জাভাস্ক্রিপ্টে ব্যাপ্তি কোডের বর্তমান প্রেক্ষাপট বোঝায়, যা জাভাস্ক্রিপ্টে ভেরিয়েবলের অ্যাক্সেসযোগ্যতা নির্ধারণ করে। Scope দুটি ধরণের local এবং global: 4 | * global ভেরিয়েবল হচ্ছে ব্লকের বাইরে ঘোষিত 5 | * local ভেরিয়েবল হচ্ছে ব্লকের ভিতরে ঘোষিত 6 | 7 | নীচের উদাহরণে, আমরা একটি global variable animal তৈরি করব। ফাংশনের মধ্যে animal নামের একই একটি local variable। কনসোলে তাদের পাঠানোর মাধ্যমে, আমরা দেখতে পাচ্ছি যে কিভাবে ভেরিয়েবলের মান scopeর উপর নির্ভর করে এবং মূল মান পরিবর্তন করা হয় না। 8 | */ 9 | 10 | // Global variable initialization 11 | var animal = "Tiger"; 12 | 13 | function transform() { 14 | // A function-scoped local variable initialization 15 | var animal = "Cangaroo"; 16 | console.log(animal); 17 | } 18 | 19 | // Global and local variable log 20 | console.log(animal); 21 | transform(); 22 | console.log(animal); 23 | 24 | /* 25 | Output: 26 | 27 | Tiger 28 | Cangaroo 29 | Tiger 30 | */ -------------------------------------------------------------------------------- /basic/2. scope/Examples/example2.js: -------------------------------------------------------------------------------- 1 | /* 2 | Block scope: 3 | জাভাস্ক্রিপ্টে ব্যাপ্তি কোডের বর্তমান প্রেক্ষাপট বোঝায়, যা জাভাস্ক্রিপ্টে ভেরিয়েবলের অ্যাক্সেসযোগ্যতা নির্ধারণ করে। Scope দুটি ধরণের local এবং global: 4 | * global ভেরিয়েবল হচ্ছে ব্লকের বাইরে ঘোষিত 5 | * local ভেরিয়েবল হচ্ছে ব্লকের ভিতরে ঘোষিত 6 | 7 | নীচের উদাহরণে, আমরা একটি global variable animal তৈরি করব। ব্লকের মধ্যে animal নামের একই একটি local variable। কনসোলে তাদের পাঠানোর মাধ্যমে, আমরা দেখতে পাচ্ছি যে কিভাবে ভেরিয়েবলের মান scopeর উপর নির্ভর করে এবং মূল মান পরিবর্তন করা হয় না। 8 | */ 9 | 10 | var isInZoo = true; 11 | 12 | // A global variable initialization 13 | let animal = "Tiger"; 14 | 15 | if (isInZoo) { 16 | // A block-scoped variable initialization 17 | let animal = "Cangaroo"; 18 | console.log(`Animal is currently a ${animal}.`); 19 | } 20 | 21 | console.log(`Animal is currently a ${animal}.`); 22 | /* 23 | Output: 24 | 25 | Animal is currently a Cangaroo. 26 | Animal is currently a Tiger. 27 | */ -------------------------------------------------------------------------------- /basic/2. scope/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Scope যে শুধুমাত্র ফাংশনের মধ্যে তৈরী হয় বিষয়টি তেমন নয়। if-else কন্ডিশন, লুপ ইত্যাদি উপায়ে Scope তৈরী করা যায় এমনকি শুধুমাত্র দ্বিতীয় বন্ধনীর (Curly Braces) মাধ্যমেও Scope তৈরী করা যায়। নীচের প্রোগ্রাম লক্ষ্য করলে দেখতে পাবো যে আমরা প্রথম console.log(bike) এর মাধ্যমে Global Scope এর bike ভেরিয়েবলটি কনসোলে দেখিয়েছি, দ্বিতীয় console.log(bike) এর মাধ্যমে Local Scope এর bike ভেরিয়েবলটি কনসোলে দেখিয়েছি এবং সবশেষে console.log(bike) এর মাধ্যমে পুনঃরায় Global Scope এর bike ভেরিয়েবলটি কনসোলে দেখিয়েছি। 4 | 5 | */ 6 | 7 | let bike = 'Yamaha R15 v3'; 8 | console.log(bike); // Yamaha R15 v3 9 | 10 | { 11 | let bike = 'Suzuki Gixxer SF'; 12 | console.log(bike); // Suzuki Gixxer SF 13 | } 14 | 15 | console.log(bike); // Yamaha R15 v3 16 | 17 | 18 | /* 19 | 20 | এখানে একটি বিষয় লক্ষ্য রাখতে হবে যে, জাভাস্ক্রীপ্ট ইঞ্জিন যদি ভিন্ন Scope তৈরী না করতো তাহলে সে আমাদেরকে একই Scope এর মধ্যে একই নামে দুইটি ভিন্ন ভেরিয়েবল ব্যবহার করতে দিতো না (যদিও এই বিষয়টি var দিয়ে ডিক্লেয়ার করা ভেরিয়েবলের জন্য আলাদা হয়ে থাকে)। আরো একটি মজার বিষয় হচ্ছে যে, Global Scope ও Local Scope উভয়ের মধ্যে যদি একই নামের দুটি ভেরিয়েবল থাকে তবে Local Scope এর মধ্যে উভয় ভেরিয়েবলের এক্সেস থাকলেও Local Scope এ ডিক্লেয়ার করা ভেরিয়েবল প্রধান্য বেশি পায়। রিয়েল লাইফের ক্ষেত্রে যার এলাকা তার প্রাধান্য বেশি বিষয়টি তেমন। 21 | 22 | */ -------------------------------------------------------------------------------- /basic/2. scope/Examples/example4.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | একটা Scope এর ভিতরে ডিক্লেয়ার করা সকল ভেরিয়েবল এবং ফাংশনসমূহ ঐ Scope এর ভিতের তৈরী সকল Scope (Nested Scope) এ এক্সেস করা যায় আর এক্ষেত্রে সেটা যে কোন লেভেলে ব্যবহার করা যায়। নীচের কোডটি একটু খেয়াল করিঃ 4 | 5 | */ 6 | 7 | let companyName = 'Vivasoft Ltd.'; 8 | 9 | const fn1 = () => { 10 | const fn2 = () => { 11 | console.log(companyName); // Vivasoft Ltd. 12 | } 13 | fn2(); 14 | } 15 | const fn3 = () => { 16 | fn1(); 17 | } 18 | 19 | fn3(); 20 | 21 | /* 22 | 23 | উপরের কোডটিতে Global Scope এর জন্য companyName হলো গ্লোবাল ভেরিয়েবল এবং fn1() ও fn3() হলো গ্লোবাল ফাংশন অর্থাৎ আমরা চাইলেই আমাদের কোডের যেকোন লেভেলে এগুলোকে ব্যবহার করতে পারি। আর গ্লোবাল স্কোপ যে আমাদেরকে যেকোন লোকাল স্কোপে তার ভেরিয়েবল এবং ফাংশনসমূহ ব্যবহারের সুযোগ দিচ্ছে এটাকেই আমরা Lexical Scoping (লেক্সিক্যাল স্কোপিং) বলে থাকি। 24 | 25 | */ -------------------------------------------------------------------------------- /basic/2. scope/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/2. scope/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/2. scope/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | নীচের কোডে কোথাও ভূল আছে কিনা সেটা খুজে বের করার চেষ্টা করুন। যদি থাকে তবে সেটা কেন হচ্ছে সেটা ব্যাখ্যা করুন। 2 | 3 | ```js 4 | 5 | let myCar = 'Lamborghini Huracan Evo'; 6 | 7 | function changeCar() { 8 | let myCar = 'Ferrari SF90 Stradale'; 9 | console.log(myCar); 10 | } 11 | 12 | let myCar = 'Ford GT'; 13 | console.log(myCar); 14 | 15 | ``` 16 | 17 | 18 | নীচের কোডের আউটপুট কি হবে? 19 | 20 | ```js 21 | 22 | let secondHome = 'Canada'; 23 | 24 | function toggleHome() { 25 | let secondHome = 'Australia'; 26 | secondHome = 'USA'; 27 | } 28 | 29 | toggleHome(); 30 | 31 | console.log(secondHome); // What will be the output? 32 | 33 | ``` -------------------------------------------------------------------------------- /basic/2. scope/README.md: -------------------------------------------------------------------------------- 1 | ### Scope কি? 2 | 3 | > **Scope** মূলত একটা নির্দিষ্ট সীমানাকে বোঝায়। যার বাহিরে **Variable** এবং **Function**-গুলো এক্সেসিবল না। যদি এই সীমানার বাহিরে কোন **Variable** এবং **Function** কে কল করা হয় তাহলে তার কোন অস্তিত্ব থাকবে না। একটি কথা ভাল করে মাথায় সংরক্ষণ করে রাখেন যে, জাভাস্ক্রিপ্টে একমাত্র তখনই **Scope** তৈরি হয়, যখন আমরা কোন **function** ইনভোক বা কল করি। হ্যাঁ, **function** ছাড়া আর কোথাও **Scope** তৈরি হয় না। আর এই **Scope** হচ্ছে দুই প্রকার- ১. **Global Scope** এবং ২. **Local Scope**। 4 | 5 | ### ১. Global Scope 6 | 7 | জাভাস্ক্রিপ্টে বাই ডিফল্ট সব কিছু **Global Scope** - এ রান হয়। যার এক্সেসিবল সব জায়গায় থাকে। উদাহরণস্বরূপ- 8 | 9 | ```js 10 | var globalVariable = "I am global variable."; 11 | console.log(globalVariable); // I am global variable. 12 | 13 | var myFunc = function () { 14 | console.log(globalVariable); 15 | }; 16 | 17 | myFunc(); // I am global variable. 18 | ``` 19 | 20 | উপরের কোডটুকু রান করলে দেখতে পারবেন যে globalVariable নামের ভেরিয়েবলটিকে সব যায়গায় ব্যবহার করা যাচ্ছে এবং সবার আউটপুটও একই দেখাচ্ছে। 21 | 22 | ### ২. Local Scope 23 | 24 | আগেই বলেছিলাম যে, জাভাস্ক্রিপ্ট একমাত্র তখনই **Scope** তৈরি করে যখন কোন **Function** কে ইনভোক বা কল করা হয়। এই **Scope** কেই বলা হয় **Local Scope**। মানে হচ্ছে, তার ভিতরে যা কিছু থাকবে তার নিজস্ব **Scope** - এর বাহিরে এর কোন অস্তিত্ব থাকবে না। অর্থাৎ, তার **Scope** - এর ভিতরে লেখা কোন ভেরিয়েবলকে যদি আমরা বাহিরে অন্য কোথাও ব্যবহার করতে চাই তাহলে জাভাস্ক্রিপ্ট খুব সুন্দর করে একটি আনকট রেফারেন্সে ইরর দিয়ে বলে দিবে যে খোকা তুমি যাকে ব্যবহার করতে চাচ্ছ সে তো কোথাও ডিফাইন করা নেই। চলুন একটা উদাহরণ দিয়ে দেখা যাক- 25 | 26 | ```js 27 | var globalVariable = "I am global variable."; 28 | 29 | var myFunc = function () { 30 | var localVariable = "I am local variable."; 31 | 32 | console.log(globalVariable); 33 | console.log(localVariable); 34 | }; 35 | 36 | myFunc(); 37 | // I am global variable. 38 | // I am local variable. 39 | 40 | console.log(localVariable); // undefined 41 | ``` 42 | 43 | উপরের কোডটুকু রান করলে দেখতে পারবেন যে প্রথমে দেখাচ্ছে I am global variable. এবং I am local variable. তারপর অতি ভদ্রতার সাথে খুব সুন্দর করে এরর দিয়ে বলে দিছে যে **Uncaught ReferenceError: localVariable is not defined**। 44 | 45 | ### Lexical Scoping কি? 46 | 47 | এখন সবার মনে প্রশ্ন আসতে পারে যে, এই **Lexical Scoping** - টা আবার কি? একটু অপেক্ষা করেন মাথা গরম করার কোন দরকার নেই। আসলে জাভাস্ক্রিপ্টকে বলা হয় **Lexical Scoping** ল্যাঙ্গুয়েজ। আমরা ফাংশনের ভিতরে আমাদের প্রয়োজন অনুযায়ী একাধিক ফাংশন তৈরি করতে পারি এবং চাইল্ড ফাংশনগুলো তার প্যারেন্ট ফাংশনের সব ভেরিয়েবলস এবং আর্গুমেন্টেসের এক্সেস পায়। কিন্তু আউটার ফাংশনগুলো তার চাইল্ড ফাংশনের ভেরিয়াবলস এবং আর্গুমেন্টসের কোন এক্সেস পায় না। এই যে চাইল্ড ফাংশনগুলো তার প্যারেন্ট ফাংশনের ভেরিয়েবলস এবং আর্গুমেন্টেসের এক্সেস পাচ্ছে এই এক্সেস পাওয়াকেই বল হয় **Lexical Scoping**। 48 | 49 | ```js 50 | function outerFunc(a) { 51 | var outerFuncVariable = "Hi there, I am outer " + a; 52 | 53 | console.log(outerFuncVariable); // Hi there, I am outer function variable 54 | 55 | function innerFunc() { 56 | var innerFuncVariable = "Hi there, I am inner " + a; 57 | console.log(innerFuncVariable); // Hi there, I am inner function variable 58 | } 59 | 60 | innerFunc(); 61 | 62 | console.log(innerFuncVariable); // undefined 63 | } 64 | 65 | outerFunc("function variable"); 66 | ``` 67 | 68 | **নোটসঃ** 69 | 70 | - জাভাস্ক্রিপ্টের গ্লোবাল স্কোপ এবং লোকাল স্কোপ আছে। 71 | - যে কোন ফাংশনের বাইরে ডিক্লেয়ারড এবং ইনিশিয়ালাইজড ভ্যারিয়েবলগুলো গ্লোবাল ভ্যারিয়েবল হয়ে যায়। 72 | - ফাংশনের ভিতরে ডিক্লেয়ারড এবং ইনিশিয়ালাইজড ভ্যারিয়েবলগুলো সেই ফাংশনের লোকাল ভ্যারিয়েবল হয়। 73 | - গ্লোবাল ভ্যারিয়েবলগুলো প্রোগ্রামের যেকোন জায়গায় অ্যাক্সেস এবং পরিবর্তন করা যেতে পারে। 74 | - ফাংশন ডিক্লেয়ারেশনের বাইরে লোকাল ভ্যারিয়েবল সমূহ অ্যাক্সেস করা যাবে না। 75 | - গ্লোবাল ভ্যারিয়েবল এবং লোকাল ভ্যারিয়েবল একই নাম থাকতে পারে। কিন্তু একই নাম ব্যবহার না করায় ভালো। 76 | 77 | 78 | ### আরও বাংলা টিউটোরিয়াল 79 | > - [জাভাস্ক্রিপ্টঃ স্কোপ(Scope) নিয়ে ধারণা](https://js.zonayed.me/basic/post-15) 80 | 81 | > - [জাভাস্ক্রিপ্ট স্কোপ (JavaScript Scope)](http://bangla.salearningschool.com/recent-posts/জাভাস্ক্রিপ্ট-স্কোপ-javascript-scope/) 82 | 83 | 84 | ### বাংলা ভিডিও টিউটোরিয়াল 85 | > - [JavaScript Scope and Hoisting Explained | JavaScript Bangla Tutorial](https://www.youtube.com/watch?v=6_4NcQQvxmM) 86 | 87 | > - [Scope and Scope Variables | Ultimate Beginner JavaScript Course](https://www.youtube.com/watch?v=HZZ0X2Toiok&t=40s) 88 | 89 | 90 | > - [Javascript Behind The Scene Scope Chain and Lexical Scope in Bangla](https://www.youtube.com/watch?v=LPB6oT_pvu4) 91 | -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example1.js: -------------------------------------------------------------------------------- 1 | console.log(x) 2 | let x = 5 3 | 4 | {/* 5 | output: 6 | Uncaught ReferenceError: x is not defined 7 | */} 8 | 9 | console.log(x) 10 | const x = 5 11 | 12 | {/* 13 | output: 14 | Uncaught ReferenceError: x is not defined 15 | */} 16 | 17 | console.log(x) 18 | var x = 5 19 | 20 | {/* 21 | output: 22 | undefined 23 | */} 24 | -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example2.js: -------------------------------------------------------------------------------- 1 | 2 | hoistedSuccess(); // Hoisted 3 | 4 | function hoistedSuccess() { 5 | console.log("This is Function Statement and it is hoisted"); 6 | } 7 | 8 | {/* 9 | output: 10 | This is Function Statement and it is hoisted 11 | */} 12 | 13 | 14 | hoistedFailed(); // Hoisted 15 | 16 | const hoistedFailed =()=>{ 17 | console.log("This function expression so it is not hoisteed."); 18 | } 19 | 20 | {/* 21 | output: 22 | Uncaught ReferenceError: hoistedFailed is not defined 23 | */} -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example3.js: -------------------------------------------------------------------------------- 1 | var outerVar= "Hi , this is outer variable."; 2 | 3 | function hoistingFunc() { 4 | console.log(outerVar); 5 | var outerVar = "Hi , this is inner variable."; 6 | console.log(outerVar); 7 | } 8 | 9 | hoistingFunc(); 10 | 11 | {/* 12 | output: 13 | undefined 14 | Hi , this is inner variable. 15 | */} 16 | -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example4.js: -------------------------------------------------------------------------------- 1 | function codeHoist(){ 2 | a = 10; 3 | let b = 50; 4 | } 5 | codeHoist(); 6 | 7 | console.log('value of a is ',a); 8 | console.log('value of b is ',b); 9 | 10 | {/* 11 | output: 12 | value of a is 10 13 | Uncaught ReferenceError: b is not defined 14 | */} -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example5.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('value of a is ',a); 3 | function codeHoist(){ 4 | a = 10; 5 | } 6 | codeHoist(); 7 | 8 | {/* 9 | output: 10 | ReferenceError: a is not defined 11 | */} -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example6.js: -------------------------------------------------------------------------------- 1 | console.log(x); // x is undefined 2 | 3 | x = 5; // Assign 5 to x 4 | 5 | console.log(x); // x is 5 6 | 7 | var x; // Declare x 8 | 9 | /* 10 | Output: 11 | undefined 12 | 5 13 | */ -------------------------------------------------------------------------------- /basic/3. hoisting/Examples/example7.js: -------------------------------------------------------------------------------- 1 | var x = 5; // Initialize x 2 | 3 | console.log(x + " " + y); 4 | 5 | var y = 7; // Initialize y 6 | 7 | console.log(x + " " + y); 8 | 9 | /* 10 | Output: 11 | 5 undefined 12 | 5 7 13 | */ -------------------------------------------------------------------------------- /basic/3. hoisting/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/3. hoisting/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/3. hoisting/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | নীচের কোডের আউটপুট কি হবে? 2 | 3 | ```js 4 | 5 | sayHi(); 6 | console.log(sayHello); 7 | 8 | function sayHi() { 9 | var sayHello = 'Hi!'; 10 | console.log(sayHello); 11 | } 12 | 13 | var sayHello = 'Hello!'; 14 | 15 | ``` -------------------------------------------------------------------------------- /basic/3. hoisting/README.md: -------------------------------------------------------------------------------- 1 | এই লেখাটি পড়ার আগে আমার **Execution Context** এবং **Scope** নিয়ে লেখা দুটি আর্টিকেল পড়ে আসতে বলবো। তাহলে **Hoisting** বুঝতে আপনার জন্যে অনেক সহজ হয়ে যাবে। 2 | 3 | ১। [Execution Context](../1.%20execution-context/README.md) 4 | 5 | ২। [Scope](../2.%20scope/README.md) 6 | 7 | ### Hoisting কি? 8 | 9 | > **Hoisting** হচ্ছে জাভাস্ক্রিপ্ট এমন একটি পদ্ধতি যেখানে কোড এক্সিকিউশন করার আগে ভ্যারিয়েবল এবং ফাংশন ডিক্লেয়ারেশনগুলোকে তার বর্তমান **Scope** - এর শুরুতে নিয়ে যায়। 10 | 11 | উদাহরণস্বরূপঃ 12 | 13 | ```js 14 | function hoisting() { 15 | console.log(message); 16 | var message='Hi there, We are learning Hoisting!' 17 | } 18 | 19 | hoisting(); // Ouput: undefined 20 | ``` 21 | উদাহরণের ব্যাখ্যা দেওয়ার আগে Hoisting সম্পর্কে কিছু কথা বলে নেই। যখন আমরা কাউকে Hoisting বুঝায় উপরের সংজ্ঞাটা দিয়েই বুঝায়। কিন্তু আসলেই কি জাভাস্ক্রিপ্ট তার সকল ভ্যারিয়েবলস এবং ফাংশন ডিক্লেয়ারেশনগুলোকে তার স্কোপের উপরে নিয়ে যায়? না, জাভাস্ক্রিপ্ট এমনটা কখনো করে না। যদি আপনি আমার [Execution Context](https://shahansdiary.com/execution-context-in-javascript/) নিয়ে লেখাটা পড়ে থাকেন, তাহলে আপনি জানেন যে যখন আপনি জাভাস্ক্রিপ্টের কোন কোড এক্সিকিউট করেন, জাভাস্ক্রিপ্ট ইঞ্জিন গ্লোবাল এক্সিকিউশন কন্টেক্সট তৈরি করে। 22 | 23 | গ্লোবাল এক্সিকিউশন কন্টেক্সট এর দুটি phase আছে: **creation** এবং **execution**। creation phase চলার সময়, জাভাস্ক্রিপ্ট ইঞ্জিন সকল ভ্যারিয়েবলকে **undefined** হিসাবে ইনিশিয়ালাইজ করে। এবার চলুন আমরা **Hoisting**-এ ফিরে যাই। 24 | 25 | জাভাস্ক্রিপ্টে **Hoisting** হচ্ছে দুই প্রকার। ১. **Variable Hoisting** এবং ২. **Function Hoisting**। 26 | 27 | ১. Variable Hoisting 28 | 29 | ```js 30 | console.log(hoistingIntro); // Output: undefined 31 | 32 | var hoistingIntro = "Hi there, I am a string one."; 33 | ``` 34 | 35 | উপরের console.log এর আউটপুট কি হবে? একটু চিন্তা করুন সময় নিয়ে। যাইহোক, উপরের কোডে কোন ভুল নেই। কারণ আমরা জানি জাভাস্ক্রিপ্ট ইঞ্জিন **Creation phase**-এ ভ্যারিয়েবল ডিক্লেয়ারেশনকে **undefined** হিসাবে ইনিশিয়ালাইজ করে। তাই, **Execution phase**-এ আউটপুট **undefined** হচ্ছে কারণ আমরা তার ভ্যালু ইনিশিয়ালাইজ হওয়ার আগেই log করে ফেলেছি। টেকনিক্যালি, কোডটি Execution phase-এ নিম্নলিখিত কোডের মত দেখাবেঃ 36 | 37 | ```js 38 | var hoistingIntro = undefined; 39 | 40 | console.log(hoistingIntro); // output: undefined 41 | hoistingIntro = "Hi there, I am a string one."; 42 | ``` 43 | 44 | ### ২। Functions Hoisting 45 | 46 | ভ্যারিয়েবলের মত ফাংশনও Hoisted হয়। তাই আপনি আগে ফাংশন কল করে পরে ফাংশন ডিক্লেয়ার করতে পারবেন। 47 | 48 | ```js 49 | hoistedFunc(); // Hoisted 50 | 51 | function hoistedFunc() { 52 | console.log("Hoisted."); 53 | } 54 | ``` 55 | বিঃ দ্রঃ একটি কথা ভাল করে মনে রাখবেন যে জাভাস্ক্রিপ্ট ফাংশন এক্সপ্রেশনের ক্ষেত্রে কোন Hoisting করে না। 56 | 57 | ```js 58 | hoistedFunEx(); // TypeError: hoistedFunEx is not a function 59 | 60 | var hoistedFunEx = function() { 61 | console.log("Hoisted."); 62 | } 63 | ``` 64 | আপনাদের জন্যে একটি হোম টাস্ক। নিচের কোডের দুইটা console.log এর আউটপুট কি হবে? চাইলে কমেন্ট করে জানাতে পারেন। :) 65 | 66 | ```js 67 | var hoistingIntro = "Hi there, I am a string one."; 68 | 69 | function hoistingFunc() { 70 | console.log(hoistingIntro); 71 | var hoistingIntro = "Hi there, I am a string two"; 72 | console.log(hoistingIntro); 73 | } 74 | 75 | hoistingFunc(); 76 | ``` 77 | 78 | ### আরও বাংলা টিউটোরিয়াল 79 | > - [জাভাস্ক্রিপ্টঃ স্কোপ(Scope) নিয়ে ধারণা](https://js.zonayed.me/basic/post-15) 80 | 81 | > - [জাভাস্ক্রিপ্ট স্কোপ (JavaScript Scope)](http://bangla.salearningschool.com/recent-posts/জাভাস্ক্রিপ্ট-স্কোপ-javascript-scope/) 82 | 83 | 84 | ### বাংলা ভিডিও টিউটোরিয়াল 85 | > - [JavaScript Scope and Hoisting Explained | JavaScript Bangla Tutorial](https://www.youtube.com/watch?v=6_4NcQQvxmM) 86 | 87 | > - [Scope and Scope Variables | Ultimate Beginner JavaScript Course](https://www.youtube.com/watch?v=HZZ0X2Toiok&t=40s) 88 | 89 | 90 | > - [Javascript Behind The Scene Scope Chain and Lexical Scope in Bangla](https://www.youtube.com/watch?v=LPB6oT_pvu4) 91 | -------------------------------------------------------------------------------- /basic/4. closure/Examples/Anonymous_fn_with_lexical_scope.js: -------------------------------------------------------------------------------- 1 | {/* 2 | Here the Anonymous function (within multiply function) creates a closure with x. 3 | so when multiply function called , it returns Anonymous function. We define that 4 | function in multiplyFive variable.Although multiply function already called and 5 | remove from the call stack but multiplyFive have now the access of variable x from closure. 6 | */} 7 | 8 | const multiply = (x)=> { 9 | return function(y) { 10 | return x * y; 11 | } 12 | } 13 | 14 | let multiply10 = multiply(10); 15 | let multiplyFive = multiply10(5); 16 | 17 | console.log(multiplyFive); 18 | 19 | //Output 50 20 | -------------------------------------------------------------------------------- /basic/4. closure/Examples/Closure_In_InnerFunction.js: -------------------------------------------------------------------------------- 1 | //ex:1 2 | function add() { 3 | let counter = 0; 4 | function plus() {counter += 1;} 5 | plus(); 6 | return counter; 7 | } 8 | add() 9 | add() 10 | add() 11 | {/* 12 | output: 13 | 1 14 | */} 15 | 16 | //ex:2 17 | {/* 18 | Closure in self invoking function 19 | A closure is a function having access to the parent scope, 20 | even after the parent function has closed. 21 | Here the self invoking Anonymous function will create closure with counter variable. 22 | and each time the add function called , Anonymous function function will execute 23 | and increment the value of counter(closure) by 1. 24 | */} 25 | 26 | const add = (function () { 27 | let counter = 0; 28 | return function () {counter += 1; return counter} 29 | })(); 30 | 31 | add(); 32 | add(); 33 | add(); 34 | 35 | 3 36 | 37 | {/* 38 | output: 39 | 3 40 | 41 | */} -------------------------------------------------------------------------------- /basic/4. closure/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/4. closure/Examples/closure.js: -------------------------------------------------------------------------------- 1 | var langFunc = function () { 2 | var langName = "JavaScript"; 3 | // displayLangName is a inner function of langFunc 4 | function displayLangName() { 5 | console.log(langName); 6 | } 7 | return displayLangName; 8 | }; 9 | 10 | langFunc()(); 11 | 12 | /* 13 | Output: 14 | JavaScript 15 | */ 16 | -------------------------------------------------------------------------------- /basic/4. closure/Examples/closure_scope_chain.js: -------------------------------------------------------------------------------- 1 | {/* 2 | Every closure has three scopes: 3 | 4 | Local Scope (Own scope) 5 | Outer Functions Scope 6 | Global Scope 7 | 8 | Here's a series of nested functions, 9 | all of which have access to the outer 10 | functions' scope. In this context, 11 | we can say that closures have access to all outer function scopes. 12 | 13 | */} 14 | 15 | // global scope 16 | var e = 10; 17 | function sum(a){ 18 | return function(b){ 19 | return function(c){ 20 | // outer functions scope 21 | return function(d){ 22 | // local scope 23 | return a + b + c + d + e; 24 | } 25 | } 26 | } 27 | } 28 | 29 | console.log(sum(1)(2)(3)(4)); // log 20 -------------------------------------------------------------------------------- /basic/4. closure/Examples/emulating_private_methods_with_closures.js: -------------------------------------------------------------------------------- 1 | // জাভার মতো ভাষাগুলি আপনাকে method private হিসাবে declare করার অনুমতি দেয়, 2 | // অর্থাত্ তাদের একই class এর অন্যান্য methods দ্বারা call করা যেতে পারে। 3 | // জাভাস্ক্রিপ্ট এটি করার একটি native way প্রদান করে না, 4 | // কিন্তু Closure ব্যবহার করে private method অনুকরণ করা সম্ভব। 5 | // private method গুলি কেবল কোডে অ্যাক্সেস সীমাবদ্ধ করার জন্য কার্যকর নয়। 6 | // তারা আপনার global namespace পরিচালনার একটি শক্তিশালী উপায়ও প্রদান করে। 7 | 8 | var counter = (function () { 9 | var privateCounter = 0; 10 | function changeByValue(val) { 11 | privateCounter += val; 12 | } 13 | 14 | return { 15 | increment: function () { 16 | changeByValue(1); 17 | }, 18 | 19 | decrement: function () { 20 | changeByValue(-1); 21 | }, 22 | 23 | value: function () { 24 | return privateCounter; 25 | }, 26 | }; 27 | })(); 28 | 29 | // Initial call privateCounter 30 | console.log(counter.value()); 31 | 32 | // privateCounter increment by 1 33 | counter.increment(); 34 | // again privateCounter increment by 1 35 | counter.increment(); 36 | console.log(counter.value()); 37 | 38 | // privateCounter decrement by 1 39 | counter.decrement(); 40 | console.log(counter.value()); 41 | 42 | 43 | /* 44 | Output: 45 | 0 46 | 2 47 | 1 48 | */ -------------------------------------------------------------------------------- /basic/4. closure/Examples/example_for_understand_usecase_of_closure.js: -------------------------------------------------------------------------------- 1 | {/* 2 | This is an example that show another use case of closure. 3 | Var keyword has functional scope. so when we create variable using 4 | var keyword with the same variable name, its always point to the same variable. 5 | Here we use asynchronous function setTimeout. when settimeout 6 | asynchronously executed after timeout, the value of count 7 | has been already became 6. Because it will continue the loop upto 5 and then another 8 | increment operation increment the value of count to 6. so it will print 6 for five time 9 | We can solve these issue using closure 10 | */} 11 | 12 | for(var count = 1; count <= 5; count++) { 13 | setTimeout(() => console.log(count), 1000); 14 | } 15 | 16 | {/* 17 | Output: 18 | 6 19 | 6 20 | 6 21 | 6 22 | 6 23 | */} -------------------------------------------------------------------------------- /basic/4. closure/Examples/solve_var_functional_scope_issue_using_closure.js: -------------------------------------------------------------------------------- 1 | //ex:1 2 | 3 | {/* 4 | In these example We have solve the previous issue 5 | in two differents way. First one using Closure. 6 | Here we called an Anonymous function in every iteration. 7 | We know function create closure with its lexical scope. 8 | So These Anonymous function will creates closure with count variable. 9 | When the Timeout finished , it will print the value from closure. 10 | */} 11 | for(var count = 1; count <= 5; count++) { 12 | (function (){ 13 | var closurVar=count 14 | setTimeout(() => console.log(closurVar), 1000); 15 | 16 | })() 17 | } 18 | 19 | {/* 20 | Output: 21 | 1 22 | 2 23 | 3 24 | 4 25 | 5 26 | */} 27 | 28 | 29 | 30 | 31 | //ex:2 32 | 33 | {/* 34 | let has block scope and var has functional skope. 35 | so let create differents variable in every time where 36 | var point to the same variable every time. 37 | */} 38 | 39 | for(let count = 1; count <= 5; count++) { 40 | setTimeout(() => console.log(count), 1000); 41 | } 42 | {/* 43 | Output: 44 | 1 45 | 2 46 | 3 47 | 4 48 | 5 49 | 50 | 51 | */} -------------------------------------------------------------------------------- /basic/4. closure/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/4. closure/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/4. closure/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | নীচের প্রোগ্রামের আউটপুট কি হবে সেটা রান না করে নিজেই অনুমান করার চেষ্টা করো। তোমার অনুমানকৃত আউটপুট কোথাও লিখে রাখো। এবার প্রোগ্রামটি রান করে আউটপুট দেখো। যদি সেটা তোমার আউটপুটের সাথে মিলে যায় তাহলে তোমাকে কনগ্রাচুলেশনস, তুমি ক্লোজার বিষয়টি রপ্ত করতে পেরেছো। আর যদি তোমার আউটপুটের সাথে না মিলে তাহলে ক্লোজার টপিকটি আরেকটিবার ভালো করে পড়ো এবং প্রোগ্রামের আউটপুট কেন এমন হচ্ছে সেটা বোঝার চেষ্টা করো। 2 | 3 | ```js 4 | 5 | setTimeout(() => console.log('First Output:'), 1000); 6 | for(var i = 1; i <= 5; i++) { 7 | setTimeout(() => console.log(i), 1000); 8 | } 9 | 10 | setTimeout(() => console.log('\nSecond Output:'), 2000); 11 | for(var i = 1; i <= 5; i++) { 12 | function a(i) { 13 | setTimeout(() => console.log(i), 2000); 14 | } 15 | a(i); 16 | } 17 | 18 | ``` -------------------------------------------------------------------------------- /basic/4. closure/README.md: -------------------------------------------------------------------------------- 1 | ## পূর্বশর্ত 2 | 3 | ২। [Scope](../2.%20scope/README.md) 4 | 5 | ## ক্লোজার কি? 6 | 7 | > Closure কোন ফাংশন না আবার ফাংশনও কোন closure না। Closure হচ্ছে ফাংশনের এমন একটা বৈশিষ্ট্য যে বৈশিষ্ট্যের কারণে ফাংশন এক্সিকিউশন শেষ হয়ে যাবার পরেও তার lexical scope এ অবস্থিত সকল variable কে মনে রাখতে পারে। উদাহরণস্বরূপ বলা যেতে পারে যে ডম থেকে কিছু অ্যাক্সেস করার জন্যে আমরা যে ইভেন্ট ফাইয়ার করি সেটাও একটা closure। 8 | 9 | ### কিছু উদাহরণঃ 10 | 11 | ```js 12 | function add(a) { 13 | return function (b) { 14 | return a + b; 15 | }; 16 | } 17 | 18 | let addTen = add(10); 19 | let addSeven = addTen(7); 20 | 21 | console.log(addSeven); // 17 22 | ``` 23 | 24 | কি হচ্ছে এসব?? ঠিক আছে, চলেন দেখি কোডগুলোকে ভেঙ্গেঃ- 25 | 26 | ১। যখন add ফাংশনটি কল হয় এটি আরেকটি ফাংশনকে return করে। 27 | ২। ঐ ফাংশনটির এক্সিকিউশন শেষ হয়ে যায় এবং মনে রাখে ঐ সময় তার প্যারামিটার a এর ভ্যালু কি ছিল। 28 | ৩। যখন addTen ভেরিয়েবলে add ফাংশনকে এসাইন করা হয়। এটি সব সময় মনে রাখবে a এর ভেল্যু কি ছিল যখন এটিকে ইনিশিয়ালি কল করা হয়েছিল। 29 | ৪। উপরের addTen ভেরিয়েবল একটি ফাংশনকে বোঝায় যেটি সব সময় ভেল্যু ১০ যোগ করবে যা পাঠানো হয়েছিল। 30 | ৫। তার মানে হল যখন addTen কে কল করা হয় ৭ ভেল্যু দিয়ে, এটি ১০ এর সাথে ৭ যোগ করবে এবং ১৭ রিটার্ন করবে। 31 | 32 | **সুতারং, জাভাস্ক্রিপ্ট ইঞ্জিন addTen কে যেভাবে রান করেঃ-** 33 | 34 | ```js 35 | function addTen(b) { 36 | return 10 + b; 37 | } 38 | ``` 39 | 40 | এখন একটা মজার উদাহরণ দেখবো। কিভাবে আমরা লুপের ভিতরে ক্লোজার চালাতে পারি। এটি ইন্টার্ভিউ বোর্ডের একটা কমন প্রশ্ন। নিচের কোডটা দেখেন এবং একটু মনে মনে চিন্তা করেন এটার আউটপুট কত হবে। 41 | 42 | ```js 43 | for (var i = 1; i <= 5; i++) { 44 | setTimeout(() => console.log(i), 1000); 45 | } 46 | ``` 47 | 48 | **কাঙ্খিত আউটপুটঃ-** 49 | 50 | ``` 51 | 1 52 | 2 53 | 3 54 | 4 55 | 5 56 | ``` 57 | 58 | **কিন্তু আসছে অনাকাঙ্ক্ষিত আউটপুটঃ-** 59 | 60 | ``` 61 | 6 62 | 6 63 | 6 64 | 6 65 | 6 66 | ``` 67 | 68 | আসলে এই আউটপুট আসার অনেক কারণ আছে। লুপের মাঝে ভ্যারিয়েবল i হচ্ছে একটি গ্লোবাল ভ্যারিয়েবল। যখন setTimeout রান হয় তার আগেই লুপ শেষ হয়ে যায় এবং তাই i ভ্যালু 6 হয়ে যায়। সেজন্যে প্রতি এক সেকেন্ড পর পর পাঁচবার 6 দেখাচ্ছে। যদি বিশ্বাস না হয় তাহলে কোডটা রান করার পর আপনার গ্লোবাল window অবজেক্টটা একবার দেখেন সেখানে i নামে একটা ভ্যারিয়াবল দেখতে পারবেন এবং তার ভ্যালু 6 হয়ে আছে। 69 | 70 | এই সমস্যার সমাধান আমরা IIFE বা Immediately Invoked Function Expression ব্যবহার করে করতে পারি। নিচে উদাহরণ দেওয়া হলোঃ- 71 | 72 | **পদ্ধতি ১ঃ-** 73 | 74 | ```js 75 | for (var i = 1; i <= 5; i++) { 76 | (function () { 77 | var val = i; 78 | setTimeout(() => console.log(val), 1000); 79 | })(); 80 | } 81 | ``` 82 | 83 | **পদ্ধতি ২ঃ-** 84 | 85 | ```js 86 | for (var i = 1; i <= 5; i++) { 87 | (function (val) { 88 | setTimeout(() => console.log(val), 1000); 89 | })(i); 90 | } 91 | ``` 92 | 93 | এখানে আমরা একটা ফাংশন লিখে একটা Scope তৈরি করেছি। ফাংশনটিকে ইমিডিয়েটলি কল করেছি এবং তার প্যারামিটারের ভেল্যু হিসাবে i কে পাস করেছি। এতে সে এখন i এর ভেল্যুকে মনে না রেখে সে এখন তার প্যারামিটারের ভেল্যুকে মনে রাখবে। মানে এখন i এর মান 1, 2 করে যাচ্ছে এবং সেটা থেকে একটা আলাদা Scope তৈরি হচ্ছে যেটাকে সে মনে রাখছে। 94 | 95 | **পদ্ধতি ৩ঃ-** 96 | 97 | ```js 98 | for (let i = 1; i <= 5; i++) { 99 | setTimeout(() => console.log(i), 1000); 100 | } 101 | ``` 102 | 103 | **আউটপুটঃ-** 104 | 105 | ``` 106 | 1 107 | 2 108 | 3 109 | 4 110 | 5 111 | ``` 112 | 113 | অবশেষে আমাদের কাঙ্ক্ষিত আউটপুট পেলাম। তবে আজ এই পর্যন্ত দেখা পরবর্তী অন্য টপিকে। হ্যাপি কোডিং... 114 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/example1.js: -------------------------------------------------------------------------------- 1 | /* Call By Value of primitives types এর উদাহরণ */ 2 | 3 | function multiplyByTen(value) { 4 | value = value * 10; 5 | } 6 | 7 | var number = 7; 8 | 9 | console.log("Before call: number = " + number); // 7 10 | 11 | multiplyByTen(number); 12 | 13 | console.log("After call: number = " + number); // 7 14 | 15 | /* Call By Reference of non-primitives types এর উদাহরণ */ 16 | 17 | function passByReference(person) { 18 | person.name = "Alex"; 19 | } 20 | 21 | var alam = { name: "Alam" }; 22 | 23 | console.log(alam.name); 24 | // Alam 25 | 26 | passByReference(alam); 27 | 28 | console.log(alam.name); 29 | // Alex 30 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/example2.js: -------------------------------------------------------------------------------- 1 | /* Call By Value of primitives types এর উদাহরণ */ 2 | 3 | function cube(a) { 4 | a = a * a * a; 5 | return a; 6 | } 7 | 8 | var x = 10; 9 | 10 | var result = cube(x); 11 | 12 | console.log(x); //a = 10 which is unchanged 13 | 14 | console.log(result); // 1000 15 | 16 | /* Call By Reference of non-primitives types এর উদাহরণ */ 17 | 18 | function switchOn(device) { 19 | device.isOn = true; 20 | } 21 | 22 | var phone = { 23 | isOn: false, 24 | }; 25 | 26 | switchOn(phone); 27 | 28 | console.log(phone.isOn); // true; 29 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/example3.js: -------------------------------------------------------------------------------- 1 | // Call by value for primitive type. 2 | 3 | var a = 5; 4 | var b; 5 | b = a; 6 | a = 3; 7 | console.log(a); // Output: 3 8 | console.log(b); // Output: 5 9 | 10 | // call by reference for object type 11 | 12 | var obj1 = { test : 'Test message 1' }; 13 | var obj2; 14 | obj2 = obj1; 15 | 16 | obj1.test = 'Test message 2'; 17 | console.log(obj1); // Output: { test: Test message 2 } 18 | console.log(obj2); // Output: { test: Test message 2 } -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/example4.js: -------------------------------------------------------------------------------- 1 | // call by value 2 | 3 | function printGreeting(greetName) { 4 | greetName = "Hello, " + greetName; 5 | console.log("New value: " + greetName); // Output: Hello, Anik 6 | } 7 | var greetName = 'Anik'; 8 | printGreeting(greetName); 9 | console.log("Old value: " + greetName); // Output: Anik 10 | 11 | // call by reference 12 | 13 | function modifyObj(person) { 14 | person.name = 'Fahim'; 15 | person.age = 26; 16 | } 17 | 18 | var person = { 19 | name: 'Anik', 20 | age: 25 21 | }; 22 | 23 | console.log("Initial name value: " + person.name); // Initial name value: Anik 24 | modifyObj(person); 25 | console.log("Updated name value: " + person.name); // Udated name value: Fahim 26 | 27 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Examples/example5.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Call by value বিষয়টি Primitive ডাটা টাইপের সাথে জড়িত। আবার Call by reference বিষয়টি Non-primitive বা Reference ডাটা টাইপের সাথে জড়িত। বিষয় দুটি বোঝার জন্য একটু অন্যভাবে চিন্তা করি। 4 | 5 | মনে করুন, আমি Google Doc এ একটি ফাইল খুলেছি এবং সেটাতে আপনাকেও এডিট করার পারমিশন দিয়েছি। এখন ফাইলটিতে আপনি বা আমি যেই কোন কিছু লিখি বা পরিবর্তন করি না কেন সেটা আমাদের দুজনের দিক থেকেই পরিবর্তন হবে। বিষয়টি এমন হবে না যে আপনি দেখলে এক রকম হবে আর আমি দেখলে অন্য রকম হবে। এই বিষয়টি ঠিক Call by reference এর মতো। আবার অন্যদিকে, আমার কাছে থাকা একটি ফাইলের কপি আমি আপনাকে দিলাম অর্থাৎ কপি মূলত দুটি, একটি আপনার আর অন্যটি আমার। সুতরাং আমি যদি আমার ফাইলে কোন পরিবর্তন করি তবে সেটি শুধুমাত্র আমার ফাইলেই পরিবর্তন হবে, আপনারটা যেমন ছিল বা আপনি যেভাবে পরিবর্তন করেছেন সেভাবেই থাকবে। আমাদের কারো পরিবর্তন একে অন্যের উপর কোন প্রভাব ফেলবে না। এই বিষয়টি Call by value এর মতো। আশাকরি এখন বিষয় দুটি বুঝতে কোন সমস্যা হবে না। চলুন একটা উদাহরণ দেখিঃ 6 | 7 | */ 8 | 9 | // Call By Value Part 10 | let primitiveData = 200; 11 | 12 | (function callByValue(primitiveData) { 13 | primitiveData = 404; 14 | })(primitiveData); 15 | 16 | console.log(primitiveData); // Output: 200 17 | 18 | 19 | // Call By Reference Part 20 | let nonPrimitiveData = ['Abid', 'Shahan', 'Imrul', 'Biplob']; 21 | 22 | (function callByReference(nonPrimitiveData) { 23 | nonPrimitiveData[0] = 'Tareq'; 24 | nonPrimitiveData.push('Tajnur'); 25 | })(nonPrimitiveData); 26 | 27 | console.log(nonPrimitiveData); // Output: [ 'Tareq', 'Shahan', 'Imrul', 'Biplob', 'Tajnur' ] -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | Here we are making a function for adding new properties and values to a specific object. What will be the console log value of 'person'? I want the function to return a new object by not changing the initial value of 'person' object sitting at the global scope. How can you do that? 2 | 3 | ```javascript 4 | const addNewProp = (key, value, object) => { 5 | object[key] = value; 6 | }; 7 | 8 | const person = { 9 | name: 'Anik' 10 | }; 11 | 12 | addNewProp('age', 25, person); 13 | console.log(person); 14 | ``` -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | নীচের প্রোগ্রামের আউটপুট কি হবে? যদি বুঝতে না পারেন তবে একটু একটু করে ডিবাগ করার চেষ্টা করুন। 2 | 3 | ```js 4 | 5 | let parentProperty = { 6 | house: ['Dhaka', 'Khulna', 'Sylhet'], 7 | car: 2 8 | } 9 | 10 | let childProperty = parentProperty; 11 | childProperty.car = 3; 12 | childProperty.bike = ['Yamaha', 'Honda']; 13 | 14 | console.log(parentProperty === childProperty); // True or False? 15 | parentProperty = childProperty; 16 | console.log(parentProperty === childProperty); // True or False? 17 | 18 | ``` 19 | 20 | 21 | এবার নীচের কোডের আউটপুট কি হবে সেটা বের করো। 22 | 23 | ```js 24 | 25 | let num = 1100; 26 | 27 | (function changeValue(num) { 28 | num = 1011; 29 | })(num); 30 | 31 | console.log(num); 32 | 33 | ``` -------------------------------------------------------------------------------- /basic/5. call-by-value-and-call-by-reference/README.md: -------------------------------------------------------------------------------- 1 | আজকে আমরা আলোচনা করতে যাচ্ছি Primitive এবং Reference টাইপ ডাটার মাঝে কি পার্থক্য এবং এই ডাটা টাইপগুলো কিভাবে কাজ করে। Primitive এবং Reference টাইপকে pass by value এবং pass by reference ও বলা হয়ে থাকে। একজন জাভাস্ক্রিপ্ট প্রোগ্রামার হিসাবে এই ডাটা টাইপগুলো সম্পর্কে পরিষ্কার জ্ঞান রাখা আবশ্যক। 2 | 3 | জাভাস্ক্রিপ্টে দুই টাইপের ডাটা টাইপ আছে। 4 | 1. primitive ডাটা টাইপ এবং 5 | 2. non-primitive বা reference ডাটা টাইপ 6 | 7 | জাভাস্ক্রিপ্টে Strings, Numbers, Boolean, Null, undefined এই ডাটা টাইপগুলো প্রিমিটিভ ডাটা টাইপ হিসাবে পরিচিত এবং Arrays, Objects, Function নন-প্রিমিটিভ বা রেফারেন্স ডাটা টাইপ হিসাবে পরিচিত। এদের মাঝে মৌলিক পার্থক্য হচ্ছে যে প্রিমিটিভ ডাটা immutable বা অপরিবর্তনীয় এবং নন-প্রিমিটিভ ডাটা mutable বা পরিবর্তনীয়। 8 | 9 | ### প্রিমিটিভ ডাটা টাইপ 10 | প্রমিটিভ ডাটা immutable বা অপরিবর্তনীয় ডাটা টাইপ হিসাবে পরিচিত। কারণ এই ডাটা একবার তৈরি হয়ে গেলে এটি পরিবর্তন করার কোন পথ নেই। তাহলে চলেন আপনাদের প্রমাণ করে দেখাই। 11 | 12 | ```js 13 | let str1 = "Hi there, I am a string!"; 14 | console.log(str1[1]); // "i" 15 | 16 | str1[1] = "e"; 17 | console.log(str1); // "Hi there, I am a string!" 18 | ``` 19 | 20 | উপরের কোডটা রান করলে জাভাস্ক্রিপ্টের কারিশমা দেখতে পারবেন। সব কিছু মাথার উপর দিয়ে গেল? আচ্ছা, চলেন ব্যাপারটা ব্যাখ্যা করি। আপনি হাজার বার চাইলেও স্ট্রিং এর ভ্যালু পরিবর্তন করতে পারবেন না। কারণ স্ট্রিং একটি immutable বা অপরিবর্তনীয় ডাটা। একটি কথা মনে রাখবেন যদি স্ট্রিংকে কোন ভেরিয়েবলে অ্যাসাইন করে ফেলেন এবং অ্যাসাইন করার পর স্ট্রিংকে মডিফাই করতে চান, তাহলে আপনি একটি নতুন স্ট্রিং পাবেন। যেমন- .toUpperCase(), .slice(), .trim() ইত্যাদি। 21 | 22 | ```js 23 | let str1 = "Hi there, I am a string!"; 24 | let newStr = str1.toUpperCase(); 25 | 26 | console.log(newStr); // HI THERE, I AM A STRING! 27 | console.log(str1); // Hi there, I am a string! 28 | ``` 29 | 30 | প্রিমিটিভ ডাটা টাইপগুলো একে অপরের সাথে তাদের ভ্যালু দ্বারা তুলনা করে। 31 | 32 | ```js 33 | let str1 = "Hi there, I am a string!"; 34 | let str2 = "Hi there, I am a string!"; 35 | 36 | console.log(str1 == str2); // true 37 | 38 | let num1 = 7; 39 | let num2 = 7; 40 | 41 | console.log(num1 == num2); // true 42 | ``` 43 | 44 | প্রিমিটিভ টাইপগুলো সব সময় তাদের ভ্যালু পাস করে। যখন আমরা কোন প্রিমিটিভ ডাটা টাইপকে অন্য কোন ভেরিয়েবলে অ্যাসাইন করি, তখন তার ভ্যালু কপি হয়ে নতুন ভেরিয়েবলে অ্যাসাইন হয়। 45 | 46 | ```js 47 | let num1 = 7; 48 | let num2 = num1; 49 | 50 | console.log(num1); // 7 51 | console.log(num2); // 7 52 | 53 | num2 = 8; 54 | 55 | console.log(num1); // 7 56 | console.log(num2); // 8 57 | ``` 58 | 59 | ### নন-প্রিমিটিভ ডাটা টাইপ 60 | 61 | নন-প্রিমিটিভ ডাটা mutable বা পরিবর্তনীয়। কারণ একটি নন-প্রিমিটিভ ডাটা তৈরি হয়ে যাওয়ার পরেও তার ভ্যালু পরিবর্তন হতে পারে। আমরা যখন কোন নন-প্রিমিটিভ ডাটা তৈরি করি, তখন সেই ডাটার জন্যে মেমোরিতে একটা অ্যাড্রেস তৈরি হয় এবং সেই অ্যাড্রেসটাকে মনে রেখে কোন এক জায়গায় ভ্যালুগুলোকে ষ্টোর করে রাখে। তারপর আমাদের যখন দরকার পড়ে তখন সে ঐ অ্যাড্রেসকে কল করে এবং আমাদের ডাটা প্রদান করে। এটা বুঝতে হলে আপনাকে স্ট্যাক এবং হীপ মেমোরি সম্পর্কে জানতে হবে। তবে আমি যতটুকু বললাম এখন এতটুকু মনে রাখলেই হবে। 62 | 63 | ```js 64 | let arr1 = ["JavaScript", "React", "Redux", "React-Redux"]; 65 | let arr2 = arr1; 66 | 67 | console.log(arr1); // ["JavaScript", "React", "Redux", "React-Redux"] 68 | console.log(arr2); // ["JavaScript", "React", "Redux", "React-Redux"] 69 | 70 | arr2[3] = "Redux-Toolkit"; 71 | console.log(arr1); // ["JavaScript", "React", "Redux", "Redux-Toolkit"] 72 | console.log(arr2); // ["JavaScript", "React", "Redux", "Redux-Toolkit"] 73 | ``` 74 | 75 | নন-প্রিমিটিভ বা রেফারেন্স ডাটাগুলো সব সময় তাদের রেফারেন্স পাস করে। যখন আমরা কোন রেফারেন্স ডাটাকে অন্য কোন ভেরিয়েবলে অ্যাসাইন করি, তখন তার রেফারেন্স কপি হয়। মানে arr1 কে যখন আমরা arr2 তে অ্যাসাইন করি তখন তার রেফারেন্স বা অ্যাড্রেসটাকে কপি করে বা মনে রাখে তার ভ্যালুকে না। তাই দুইটা ভেরিয়েবলের অ্যাড্রেস একই থাকে। তাই যখন আমরা কোন একটি ভেরিয়েবলের ভ্যালু পরিবর্তন করি, তখন দুইটা ভেরিয়েবলেরই ভ্যালু পরিবর্তন হয়ে যায়। 76 | 77 | ```js 78 | let obj1 = { 79 | name: 'JavaScript' 80 | }; 81 | 82 | let obj2 = obj1; 83 | 84 | console.log(`${obj1.name}`); // JavaScript 85 | console.log(`${obj2.name}`); // JavaScript 86 | 87 | obj2.name = "React"; 88 | 89 | console.log(`${obj1.name}`); // React 90 | console.log(`${obj2.name}`); // React 91 | ``` 92 | 93 | আশা করি, উপরের কোডে কি হচ্ছে সেটা এখন খুব ভাল ভাবেই বুঝতে পারছেন। একটি কথা নন-প্রিমিটিভ ডাটা তাদের রেফারেন্স দ্বারা তুলনা করে। 94 | 95 | ```js 96 | let obj1 = { 97 | name: 'JavaScript' 98 | }; 99 | 100 | let obj2 = { 101 | name: 'JavaScript' 102 | }; 103 | 104 | console.log(obj1 === obj2); // false 105 | ``` 106 | 107 | এখানে দুইটা অবজেক্টের একই ভ্যালু কিন্তু যখন আমরা দুইটা অবজেক্টকে একে-অপরের সাথে তুলনা করছি, তখন তারা false রিটার্ন করছে। কারণ তাদের ভ্যালু একই হলেও তাদের অ্যাড্রেস এক না। 108 | 109 | ```js 110 | let obj1 = { 111 | name: 'JavaScript' 112 | }; 113 | 114 | let obj2 = obj1; 115 | 116 | console.log(obj1 === obj2); // true 117 | ``` 118 | 119 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Examples/example1.js: -------------------------------------------------------------------------------- 1 | /* এখানে circleArea এবং squareArea ফাংশন দুটি হচ্ছে Callback ফাংশন 2 | আর areaCalculate ফাংশনটি হচ্ছে Higher Order ফাংশন 3 | */ 4 | 5 | function areaCalculate(arrayWidth, callback) { 6 | const area = arrayWidth.map((x) => callback(x)); 7 | return area; 8 | } 9 | 10 | function circleArea(radius) { 11 | return Math.PI * radius * radius; 12 | } 13 | 14 | function squareArea(side) { 15 | return side * side; 16 | } 17 | 18 | const array = [2, 6, 7, 8, 3, 1, 5]; 19 | 20 | var circleAreaArray = areaCalculate(array, circleArea); 21 | console.log(circleAreaArray); 22 | 23 | var squareAreaArray = areaCalculate(array, squareArea); 24 | console.log(squareAreaArray); 25 | 26 | console.log(array); 27 | 28 | /* 29 | Output: 30 | [12.566370614359172, 113.09733552923255, 153.93804002589985, 201.06192982974676, 28.274333882308138, 3.141592653589793, 78.53981633974483] 31 | [4, 36, 49, 64, 9, 1, 25] 32 | [2, 6, 7, 8, 3, 1, 5] 33 | */ 34 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Examples/example2.js: -------------------------------------------------------------------------------- 1 | // Dummy object 2 | const object = 3 | [ 4 | { framework: 'React.JS', website: 'Paypal' }, 5 | { framework: 'React.JS', website: 'Tesla' }, 6 | { framework: 'Angular', website: 'Google' }, 7 | { framework: 'Vue.JS', website: 'Vue' }, 8 | { framework: 'JavaScript', website: 'inblack67' }, 9 | ] 10 | 11 | // Higher Order Function 12 | function modifyArray(arr, callback) { 13 | return callback(arr); 14 | } 15 | 16 | // Callback function which add element to existing array 17 | function addElemToArray(item, arr) { 18 | return [ ...arr, item ]; 19 | } 20 | 21 | // Callback function for counting the occurences of a particular object key like, 'framework' 22 | function keyOccurence(key, arr) { 23 | const obj = {}; 24 | arr.forEach((data) => { 25 | if(data.hasOwnProperty(key)){ 26 | if(obj[data[key]]){ 27 | obj[data[key]]++; 28 | } 29 | else{ 30 | obj[data[key]] = 1; 31 | } 32 | } 33 | }) 34 | 35 | const occurenceCountObj = Object.keys(obj).map(k => ({ [key]: k, count: obj[k] })) 36 | 37 | return occurenceCountObj; 38 | } 39 | 40 | // Common bind wrapper for the callback function 41 | function bindWrapper(func, ...restArgs) { 42 | return func.bind(null, ...restArgs); 43 | } 44 | 45 | console.log(modifyArray(object, bindWrapper(keyOccurence, 'framework'))); 46 | /* Output: 47 | [ { framework: 'React.JS', count: 2 }, 48 | { framework: 'Angular', count: 1 }, 49 | { framework: 'Vue.JS', count: 1 }, 50 | { framework: 'JavaScript', count: 1 } 51 | ] 52 | */ 53 | console.log(modifyArray(object, bindWrapper(addElemToArray, { framework: 'Gats by', website: 'gatsby' }))); 54 | /* Output: 55 | [ { framework: 'React.JS', website: 'Paypal' }, 56 | { framework: 'React.JS', website: 'Tesla' }, 57 | { framework: 'Angular', website: 'Google' }, 58 | { framework: 'Vue.JS', website: 'Vue' }, 59 | { framework: 'JavaScript', website: 'inblack67' }, 60 | { framework: 'Gats by', website: 'gatsby' } 61 | ] 62 | */ 63 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Examples/example3.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | আমরা সাধারণত একটি ফাংশনের আর্গুমেন্ট হিসেবে ভেরিয়েবল, অ্যারে, অবজেক্ট ইত্যাদি পাঠিয়ে থাকি। যদি কোন ফাংশনকে আমরা অন্য ফাংশনের আর্গুমেন্ট হিসেবে পাঠায় তাহলে যে ফাংশনকে আর্গুমেন্ট হিসেবে পাঠাচ্ছি সেটাই Callback Function আর যে ফাংশন Callback Function কে আর্গুমেন্ট হিসেবে গ্রহন করছে সেটাই Higher Order Function. এছাড়াও যে ফাংশন তার রিটার্ন ভ্যালু হিসেবে কোন ফাংশনকে পাস করে তাকেও Higher Order Function বলে। একটু উদাহরণ দেখিঃ 4 | 5 | */ 6 | 7 | // Callback Function 8 | function sayHi(name) { 9 | console.log('Hi, ' + name + '!'); 10 | } 11 | 12 | // Higher Order Function 13 | function greetings(process, name) { 14 | process(name); 15 | console.log('Welcome to Callback and Higher Order function tutorial.'); 16 | } 17 | 18 | let student = 'Ahnaf'; 19 | greetings(sayHi, student); 20 | 21 | /** 22 | * Output: 23 | * Hi, Ahnaf! 24 | * Welcome to Callback and Higher Order function tutorial. 25 | */ 26 | 27 | // Another Higher Order Function 28 | function company() { 29 | let companyName = 'Vivasoft Ltd.'; 30 | let companyType = 'Software Company'; 31 | let companyEmail = 'contact@vivasoftltd.com'; 32 | 33 | function viewDetails() { 34 | console.log('Company Name:', companyName); 35 | console.log('Type:', companyType); 36 | console.log('Email:', companyEmail); 37 | } 38 | 39 | return viewDetails; 40 | } 41 | 42 | let myCompanyDetails = company(); 43 | myCompanyDetails(); 44 | 45 | /** 46 | * Output: 47 | * Company Name: Vivasoft Ltd. 48 | * Type: Software Company 49 | * Email: contact@vivasoftltd.com 50 | */ -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | নীচের কোডে higherOrderFunction() ফাংশনটি আসলে কোন ধরনের ফাংশন সেটি যাচাই করার চেষ্টা করুন। এবার নীচের কোডের আউটপুট কি হবে সেটা বের করার চেষ্টা করুন। 3 | 4 | ```js 5 | 6 | function higherOrderFunction() { 7 | let myName = 'Robindranath Thagore'; 8 | 9 | function displayName() { 10 | console.log(myName); 11 | } 12 | 13 | return displayName(); 14 | } 15 | 16 | let viewName = higherOrderFunction(); 17 | viewName(); 18 | 19 | ``` 20 | 21 | আসলে উপরের কোডের higherOrderFunction() ফাংশনটি একটি সাধারণ ফাংশন, এটি আসলে Higher-Order Function নয়। এমতাবস্থায় higherOrderFunction() ফাংশনটিকে Higher-Order Function বানাতে হলে কোথায় পরিবর্তন করতে হবে সেটার সমাধান করুন। -------------------------------------------------------------------------------- /basic/6. callback-and-higher-order-functions/README.md: -------------------------------------------------------------------------------- 1 | কলব্যাক ব্যাপারটি আমাদের জীবনের সাথে ব্যাপকভাবে জড়িয়ে আছে। যদি “সে” কলব্যাক না করে আপনি হয়তো “অ” হয়ে যান! ইয়ে মানে বলতে চাচ্ছিলাম যে অভিমানী নয়তো অস্থির হয়ে যান ;) আর যদি আপনার লাইফে “সে” না থাকে তবে তো কোন কথাই নেই। আমার মত বিন্দাস? । যাইহোক, আপনি “অ” হোন আর না হোন, “সে” কলব্যাক করুক আর না করুক আজকে আমরা কলব্যাক নিয়ে আলোচনা করবোই। চলুন তাহলে শুরু থেকেই শুরু করি… 2 | 3 | জাভাস্ক্রিপ্টে ফাংশন হচ্ছে একটি ফার্স্ট-ক্লাস অবজেক্ট। এই কারণে, ফাংশন ভেরিয়েবলের মাঝে এসাইন হতে পারে, অন্য একটি ফাংশনকে আর্গুমেন্ট হিসাবে নিতে পারে, ফাংশনের ভিতরেও কাজ করতে পারে এবং ফাংশন দ্বারা রিটার্নও হতে পারে। 4 | 5 | ### কলব্যাক ফাংশন কি? 6 | > সহজ কথায়, কলব্যাক ফাংশন হচ্ছে এমন একটি ফাংশন যেটি অন্য একটি ফাংশনে আর্গুমেন্ট হিসাবে পাস করা ফাংশন, যেটি কোন কাজ সম্পন্ন করার জন্যে আউটার ফাংশনের ভিতরে ইনভোক হয়। 7 | 8 | ### হাইয়ার অর্ডার ফাংশন কি? 9 | > যে ফাংশনে অন্য কোন ফাংশনকে আর্গুমেন্ট হিসাবে পাস করা হয় বা কোন ফাংশন অন্য কোন ফাংশনকে রিটার্ন করে তাকে হাইয়ার অর্ডার ফাংশন বলা হয়। বাংলায় এটাকে ঊচ্চমার্গীয় ফাংশন হিসেবে ভেবে নিতে পারেন। ঊচ্চমার্গীয় কথাবার্তা মাথার উপর দিয়ে গেলেও ঊচ্চমার্গীয় ফাংশন মাথার নিচ দিয়েই যাবে ইনশাআল্লাহ্‌, নিশ্চিত থাকুন। 10 | 11 | আমাদের এমন একটি ফাংশন আছে যেটি আর্গুমেন্ট হিসেবে একটি অ্যারে নিবে এবং সেটি কে মডিফাই করে একটি নতুন অ্যারে রিটার্ন করবে। এক্ষেত্রে, আমাদের ফাংশনটিকে যে অ্যারে দেওয়া হবে তার সাথে দুই যোগ করে নতুন একটি অ্যারে রিটার্ন করবে। 12 | 13 | ```js 14 | function modifyBy2(arr) { 15 | let output = []; 16 | 17 | for(let i = 0; i < arr.length; i++) { 18 | output.push(arr[i] + 2); 19 | } 20 | 21 | return output; 22 | } 23 | 24 | const newArr = modifyBy2([1,2,3,4,5,6]); 25 | console.log(newArr); // [3, 4, 5, 6, 7, 8] 26 | ``` 27 | 28 | এখন আমাদের আরেকটি ফাংশন আছে যেটি আর্গুমেন্ট হিসেবে একটি অ্যারে নিবে এবং যে অ্যারে দেওয়া হবে তার সাথে দুই গুণ করে নতুন একটি অ্যারে রিটার্ন করবে। 29 | 30 | ```js 31 | function multifyBy2(arr) { 32 | let output = []; 33 | 34 | for(let i = 0; i < arr.length; i++) { 35 | output.push(arr[i] * 2); 36 | } 37 | 38 | return output; 39 | } 40 | 41 | const newArr = modifyBy2([1,2,3,4,5,6]); 42 | console.log(newArr); // [2, 4, 6, 8, 10, 12] 43 | ``` 44 | 45 | এখন যদি আমরা বিয়োগ বা ভাগ করতে চাই? তাহলে আমাদেরকে আরও দুটি ফাংশন লিখতে হবে তাই না? ব্যাপারটা তাহলে কি ভাল কিছু হচ্ছে? কোড রিপিটেশন হয়ে যাচ্ছে। একটি বিষয় লক্ষ্য করেন আমাদের লেখা দুটি ফাংশনেই শুধু অপারেশনগুলা ছাড়া একই কোড লিখেছি। আমরা যদি এমন কিছু করতে পারি যে আমাদের ফাংশনে যোগ, বিয়োগ যে কাজই করুক না কেন সেটি আমরা বলে দিবো, তাহলে কেমন হয়? এখন আমরা সে কাজটাই করবো। তার জন্যে আমাদেরকে আমাদের ফাংশনের সাথে আরেকটি আর্গুমেন্ট পাস করতে হবে। যেটি আসলে আমাদের অপারেশনটা হ্যান্ডেল করবে। 46 | 47 | ```js 48 | function modifyArray(arr, fn) { 49 | let output = []; 50 | 51 | for(let i = 0; i < arr.length; i++) { 52 | output.push(fn(arr[i])); 53 | } 54 | 55 | return output; 56 | } 57 | 58 | function modifyBy2(elem) { 59 | return elem + 2; 60 | } 61 | 62 | 63 | const newArr = modifyArray([1,2,3,4,5,6], modifyBy2); 64 | console.log(newArr); // [3, 4, 5, 6, 7, 8] 65 | ``` 66 | উপরের কোডে লক্ষ্য করুন, আমরা **modifyArray** নামে একটি ফাংশন ডিফাইন করেছি যেটি দুটি আর্গুমেন্টস নিচ্ছে। একটি অ্যারে এবং অন্যটি একটি ফাংশন। সে ফাংশনে আমরা বলে দিচ্ছি তার কাজ কি হবে। সে তার কাজ সম্পন্ন করে output অ্যারেতে তার ভ্যালুটা পুশ করে দিচ্ছে এবং modifyArray ফাংশনটি কাজ সম্পন্ন করে একটি নতুন অ্যারে রিটার্ন করতেছে। এখন যদি আমরা বিয়োগ, গুণ বা ভাগ করতে চাই সেটিও খুব সহজেই করতে পারবো এই ফাংশন দিয়ে। আমাদেরকে নতুন করে কোন লজিক লেখা লাগবে না শুধু আমরা একটি নতুন ফাংশন দিয়ে দিবো এবং সেখানে বলে দিবো তাকে কি করতে হবে। তাহলে চলুন দেখি আমাদের কাজ করতে পারি কিনা। 67 | 68 | ```js 69 | function modifyArray(arr, callback) { 70 | let output = []; 71 | 72 | for(let i = 0; i < arr.length; i++) { 73 | output.push(callback(arr[i])); 74 | } 75 | 76 | return output; 77 | } 78 | 79 | function addBy2(elem) { 80 | return elem + 2; 81 | } 82 | 83 | function multifyBy2(elem) { 84 | return elem * 2; 85 | } 86 | 87 | 88 | const additionArr = modifyArray([1,2,3,4,5,6], addBy2); 89 | const multiArr = modifyArray([1,2,3,4,5,6], multifyBy2); 90 | 91 | console.log(additionArr); // [3, 4, 5, 6, 7, 8] 92 | console.log(multiArr); // [2, 4, 6, 8, 10, 12] 93 | ``` 94 | 95 | **modifyArray** ফাংশনটিতে আর্গুমেন্ট হিসাবে যে ফাংশনটিকে পাস করতেছি ওই ফাংশনটিই হচ্ছে একটি কলব্যাক ফাংশন এবং **modifyArray** ফাংশনটি হচ্ছে একটি **হাইয়ার অর্ডার ফাংশন**। 96 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_constructor_invocation.js: -------------------------------------------------------------------------------- 1 | /* নিম্নলিখিত Bike ফাংশনের */ 2 | 3 | function Bike(brand) { 4 | this.brand = brand; 5 | } 6 | 7 | Bike.prototype.getBrand = function () { 8 | return this.brand; 9 | }; 10 | 11 | /* 12 | এক্সপ্রেশন new Bike("TVS") হল Bike ফাংশনের একটি constructor invocation। 13 | */ 14 | 15 | var bike = new Bike("TVS"); 16 | console.log(bike.getBrand()); // TVS 17 | 18 | /* 19 | এখন, আপনি একটি function বা constructor হিসাবে Bike() invoke করতে পারেন। 20 | আপনি যদি new কীওয়ার্ডটি বাদ দেন তাহলে: 21 | */ 22 | 23 | var discover = Bike("Discover"); 24 | console.log(discover.brand); 25 | 26 | // Uncaught TypeError: Cannot read properties of undefined (reading 'brand') 27 | 28 | /* 29 | এই সমস্যার সমাধান: 30 | Bike() ফাংশন সবসময় কনস্ট্রাক্টর call করা হয়েছে তা নিশ্চিত করার জন্য, আপনি Bike() ফাংশনের শুরুতে একটি চেক যোগ করুন নিম্নরূপ: 31 | */ 32 | 33 | function Bike(brand) { 34 | if (!(this instanceof Bike)) { 35 | throw Error("Must use the new operator to call the Bike function"); 36 | } 37 | this.brand = brand; 38 | } 39 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_function_context_with_use_strict.js: -------------------------------------------------------------------------------- 1 | /* Function context এ this with 'use strict' mode */ 2 | 3 | function show() { 4 | "use strict"; 5 | console.log(this === undefined); // true 6 | 7 | function display() { 8 | console.log(this === undefined); // true 9 | } 10 | display(); 11 | } 12 | 13 | show(); 14 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_function_context_without_use_strict.js: -------------------------------------------------------------------------------- 1 | /* Function context এ this without 'use strict' mode */ 2 | 3 | function show() { 4 | console.log(this === window); // true 5 | } 6 | 7 | show(); // true 8 | window.show(); //true 9 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_global_context.js: -------------------------------------------------------------------------------- 1 | /* Global context এ this */ 2 | 3 | console.log(this === window); // true 4 | 5 | this.color = "Green"; 6 | 7 | console.log(this.color); // 'Green' 8 | console.log(window.color); // 'Green' 9 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_method_invocation.js: -------------------------------------------------------------------------------- 1 | /* 2 | this সেই object কে উল্লেখ করে ফাংশনটি যার একটি property. 3 | 4 | অন্য কথায়, this সেই object কে refer করে যা বর্তমানে ফাংশনটিকে কল করছে। 5 | 6 | ধরুন আপনার counter নামক একটি object আছে। এই counter object এ next() নামে একটি method আছে। 7 | 8 | যখন আপনি next() method কল করেন, আপনি এই object টি অ্যাক্সেস করতে পারেন। 9 | */ 10 | 11 | const counter = { 12 | count: 0, 13 | next: function () { 14 | return ++this.count; 15 | }, 16 | }; 17 | 18 | counter.next(); // 1 19 | counter.next(); // 2 20 | counter.next(); // 3 21 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Examples/this_in_method_invocation_with_bind.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | let bike = { 3 | brand: "TVS", 4 | getBrand: function () { 5 | return this.brand; 6 | }, 7 | }; 8 | 9 | console.log(bike.getBrand()); // TVS 10 | 11 | // নিচের comment এর ফলাফল undefined। কারণ globally এটি strict মোডে undefined এবং non-strict মোডে global object। 12 | 13 | /* 14 | let brand = bike.getBrand; 15 | 16 | console.log(brand()); // undefined. 17 | */ 18 | 19 | // এই সমস্যা সমাধানের জন্য আমাদের বাইন্ড ব্যবহার করতে হবে 20 | 21 | let brand1 = bike.getBrand.bind(bike); 22 | console.log(brand1()); // TVS 23 | 24 | let bike2 = { 25 | brand: "SINGER", 26 | }; 27 | let brand2 = bike.getBrand.bind(bike2); 28 | console.log(brand2()); // SINGER 29 | 30 | let bike3 = { 31 | brand: "DISCOVER", 32 | }; 33 | 34 | let brand3 = bike.getBrand.bind(bike3); 35 | console.log(brand3()); // DISCOVER 36 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/7. this-keyword/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | নীচের কোডের আউটপুট কি হবে? 3 | 4 | ```js 5 | 6 | function Mathematician(id, name) { 7 | this.id = id; 8 | this.name = name; 9 | } 10 | 11 | let muslimMtcn = Mathematician('101', 'Al-Khwarizmi'); 12 | console.log(muslimMtcn.name); 13 | 14 | ``` 15 | 16 | উপরের কোডটিতে যদি কোন ভূল থাকে সেক্ষেত্রে ঠিকঠাক আউটপুট পেতে হলে কি করতে হবে? -------------------------------------------------------------------------------- /basic/7. this-keyword/README.md: -------------------------------------------------------------------------------- 1 | আজকে আলোচনা করতে যাচ্ছি “this” কিওয়ার্ড নিয়ে। জাভাস্ক্রিপ্টে একটি মারাত্মক ভয়ের নাম হচ্ছে “this”। এটি খুবই গুরুত্বপূর্ণ একটা টার্মস যার সম্পর্কে পরিষ্কার ধারণা থাকা উচিত বলে আমি মনে করি। শুরুর দিকে এটা নিয়ে প্রায় সবাই একটু কনফিউশনে ভুগে। কারণ এটি এক এক সময় এক এক রকম আউটপুট দেয়। আমাদের বুঝতে হবে কেন এবং কখন কি আউটপুট দেয়। আমি চেষ্টা করবো ব্যাপারটাকে যতটা সম্ভব সহজভাবে লেখার জন্যে যাতে করে এই “this” নিয়ে আজকের পর থেকে কারোর কোন প্রকার কনফিউশন না থাকে এবং কারোর মাথার উপর দিয়ে না যায়। 2 | 3 | চলুন একটা উদাহরণ দিয়ে শুরু করা যাকঃ- 4 | 5 | ```js 6 | function myFunc() { 7 | console.log(this); 8 | } 9 | 10 | myFunc(); 11 | ``` 12 | 13 | একটু চিন্তা করুন তো এখানে myFunc() ফাংশনটিকে কে কল করতেছে। যদি এইটা ধরতে পারেন তাহলে myFunc() এর আউটপুট কি হবে সেইটাও বুঝতে পারবেন। একটু চিন্তা করুন সময় নিয়ে। 14 | 15 | আশা করি, চিন্তা করেছেন এবং ধরতেও পেরেছেন। যদি না পারেন তাহলে কোন সমস্যা নেই। একটা ব্যাপার সব সময় মাথায় রাখবেন যে “this” এর ভ্যালু কি হবে সেটা নির্ভর করে কোথায় এবং কিভাবে কল হচ্ছে তার উপর ভিত্তি করে। উপরের কোডে myFunc() কে কল করতেছে window অবজেক্ট। কারণ ব্রাউজারে সব কিছু বাই ডিফল্ট window অবজেক্টের আন্ডারে রান হয়। তার মানে হচ্ছে যে যার মাধ্যমে কল হবে “this” তাকে দেখাবে আউটপুট হিসাবে। 16 | 17 | ```js 18 | window.myFunc(); 19 | ``` 20 | 21 | যেহেতু myFunc() কে window কল করতেছে তাই myFunc() এর ভিতরে থাকা “this” - window এর সব ভ্যালুকে আউটপুট হিসাবে দেখাচ্ছে। 22 | 23 | আমরা না অনেক ভাল প্রোগ্রামার। তাই ‘use strict’; মোডে উপরের কোডটি আবার রান করুন এবং দেখুন কি হয়। 24 | 25 | 26 | **এইবার চলুন আরেকটি উদাহরণ দেখিঃ-** 27 | 28 | ```js 29 | let Person = { 30 | name: "Shahan's Diary", 31 | sayName: function() { 32 | console.log(this); 33 | } 34 | }; 35 | 36 | Person.sayName(); 37 | ``` 38 | 39 | এইবার বলুন তো উপরের কোডটির আউটপুট কি হবে। যারা বলতে পারবেন তাদের জন্যে থাকবে আমার পক্ষ থেকে একটি চকলেট। যদি উপরের বলা কথাগুলা ভালো করে পড়ে থাকেন, বুঝতে কোন অসুবিধা হওয়ার কথা না উপরের কোডের আউটপুট কি হবে। শুধু একটা কথা ভালো করে মনে রাখবেন কোন ফাংশন কল করার সময় ফাংশনের নামের ডটের আগে যে অবজেক্ট নামটা থাকবে তার ভ্যালুই দেখাবে। হ্যাঁ, আমি যদিও অবজেক্টের ভিতরে থাকা ফাংশনকে ফাংশন বলতেছি শুধু বোঝার সুবিধার জন্যে। এটা ফাংশন হবে না, কারণ অবজেক্টের ভিতরে থাকা সব ফাংশনকে বলা হয় মেথড। উপরের কোডের আউটপুট হবে নিচের দেওয়া স্নিপেটের মত। 40 | 41 | ``` 42 | {name: "Shahan's Diary", sayName: f} 43 | ``` 44 | 45 | এখন দেখবো কনস্ট্রাক্টর ফাংশনে “this” নিয়ে কিভাবে কাজ করা যায়। 46 | 47 | ```js 48 | let Person = function(fName, lName) { 49 | this.fName = fName; 50 | this.lName = lName; 51 | this.sayInfo = function() { 52 | return console.log("Hi there, Welcome to " + this.fName + " " + this.lName); 53 | } 54 | }; 55 | 56 | let person1 = new Person("Shahan's", "Diary"); 57 | 58 | person1.sayInfo(); // Hi there, Welcome to Shahan's Diary 59 | ``` 60 | 61 | 62 | আশা করি, আপনাদের “this” এর বেসিক ধারণাটা এখন পরিষ্কার হয়েছে। এখন থেকে দেখলেই বুঝবেন যে “this” কি কাজ করছে। হ্যাঁ, এই লেখাটা পড়েই আপনি “this” এর মাস্টার হয়ে যাবেন না। এর আরেকটু অ্যাডভান্সড ব্যবহার রয়েছে। সেটা আপনাদের জন্যে রেখে দিলাম। একটু কষ্ট করে নিজ দায়িত্বে দেখে নিবেন। এরপরেও, যদি মাথার উপর দিয়ে যায় তাহলে কমেন্ট বক্সে কমেন্ট করে উড়াই দিবেন, আমি ধরে নিবো। হ্যাপি কোডিং.... -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Examples/example1.md: -------------------------------------------------------------------------------- 1 | 2 | We already know the basics of event capturing and bubbling. 3 | In this example, we will dive a little deeper. 4 | The third argument of 'addEventListener' function tell 5 | whether the event will be in the capture phase or in the bubbling phase. 6 | By default it is in bubbling phase (if we provide no parameter) 7 | 8 | ```html 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Event Bubbling and Capturing 17 | 18 | 38 | 39 | 40 |
41 | Grandparent 42 |
43 | Parent 44 |
45 | Child 46 |
47 |
48 |
49 | 66 | 67 | 68 | 69 | ``` 70 | 71 | Run the code. now click on the child div. We can see that the output will be. 72 | 73 | Output: 74 | Parent clicked 75 | Child clicked 76 | Grandparent clicked 77 | 78 | We can see that the event capturing of event listeners happened first 79 | and then the event bubbling happened. 80 | This means the propagation of event listeners first goes from 81 | outside to inside and then from inside to outside in the DOM. 82 | As 'parent' div is propagated, it prints to the console first, 83 | then by follwing event capturing rules, 'child' div is clicked 84 | and 'grandparent' div is clicked. 85 | 86 | I hope things are clear now. We can play with this code as we want 87 | and see different output. 88 | -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Examples/example2.md: -------------------------------------------------------------------------------- 1 | We can stop event capturing and bubbling if we want. 2 | We can use a parameter "e" in the callback function of 3 | addEventListener function. It is an event object 4 | which has a function called stopPropagation() which helps 5 | to stop event capturing and bubbling. 6 | 7 | ```html 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | How to stop Event Capturing and Bubbling 16 | 17 | 37 | 38 | 39 |
40 | Grandparent 41 |
42 | Parent 43 |
44 | Child 45 |
46 |
47 |
48 | 66 | 67 | 68 | 69 | ``` 70 | 71 | Output: 72 | Child clicked 73 | Parent clicked 74 | 75 | If we clicked on child div, the propagation is stopped 76 | on parent div and does not move to grandparent div. 77 | Hence, the event bubbling is prevented. 78 | We can also stop capturing the same way. -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Examples/example3.md: -------------------------------------------------------------------------------- 1 | 2 | ইফেক্ট বুঝতে হলে প্রথমে এই HTML ফাইলটি আপনার ব্রাউজারে ওপেন করে মাউসের রাইট বাটন ক্লিক করে Inspect এ ক্লিক করুন। 3 | অতঃপর Console ট্যাবে ক্লিক করুন। এখন Event Bubbling ও Event Capturing কিভাবে হচ্ছে সেটা বুঝতে বক্সগুলোতে 4 | ক্লিক করে দেখুন। 5 | 6 | ```html 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Event Bubbling and Capturing 15 | 16 | 17 | 47 | 48 | 49 | 50 |

51 | Event Bubbling 52 |
53 |
54 |
55 | Click Me 56 |
57 |
58 |
59 |

60 | 61 | 62 |

63 | Event Capturing 64 |
65 |
66 |
67 | Click Me 68 |
69 |
70 |
71 |

72 | 73 | 74 | 75 | 108 | 109 | 110 | 111 | 112 | ``` 113 | 114 | addEventListener() ফাংশনের তৃতীয় argument হিসেবে আমরা যে true/false ভ্যালু দিয়েছি সেটা বাই ডিফল্ট false থাকে অর্থাৎ nested element ক্লিক করার ক্ষেত্রে সেটা বাই ডিফল্ট event bubbling করে থাকে। বিষয়টি যদি অন্যভাবে বলি তাহলে বলা যায় যে তৃতীয় আর্গুমেন্টে জিজ্ঞাসা করা থাকে এই event টি প্রথমে capture করা হবে নাকি হবে না। -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Examples/example4.md: -------------------------------------------------------------------------------- 1 | 2 | ইফেক্ট বুঝতে হলে প্রথমে এই HTML ফাইলটি আপনার ব্রাউজারে ওপেন করে মাউসের রাইট বাটন ক্লিক করে Inspect এ ক্লিক করুন। 3 | অতঃপর Console ট্যাবে ক্লিক করুন। এখন Event Bubbling ও Event Capturing কিভাবে হচ্ছে সেটা বুঝতে বক্সগুলোতে 4 | ক্লিক করে দেখুন। 5 | 6 | ```html 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Event Bubbling and Capturing 15 | 16 | 17 | 41 | 42 | 43 | 44 |

45 | Event Bubbling 46 |
47 |
48 | Click Me 49 |
50 |
51 |

52 | 53 | 54 |

55 | Event Capturing 56 |
57 |
58 | Click Me 59 |
60 |
61 |

62 | 63 | 64 | 65 | 100 | 101 | 102 | 103 | 104 | ``` 105 | 106 | এই উদাহরণে আমরা তেমন কোন নতুন কাজ করি নাই। এই উদাহরণে আমরা শুধুমাত্র প্রোসেস দুটি কিভাবে হচ্ছে সেটার একটা ভিজুয়াল ইফেক্ট তৈরী করেছি। 107 | -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | নীচের কোডটি কোন HTML ডকুমেন্ট হিসেবে সংরক্ষণ করুন এবং আপনার ব্রাউজারে ওপেন করুন। কোডটি ব্রাউজারে ওপেন করলে চারটি কালারের (লাল-সোনালী-সবুজ-আকাশি) বক্স দেখতে পাবেন। মাঝের Skyblue (আকাশি) কালারের বক্সে ক্লিক করলে ইভেন্টের সিরিয়াল কেমন হবে? 3 | 4 | ```html 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Event Bubbling and Capturing 13 | 14 | 15 | 47 | 48 | 49 |
50 |
51 |
52 |
53 | Click Me 54 |
55 |
56 |
57 |
58 | 59 | 60 | 61 | 81 | 82 | 83 | 84 | 85 | ``` -------------------------------------------------------------------------------- /basic/8. event-capturing-and-bubbling/Practices/practice2.md: -------------------------------------------------------------------------------- 1 | What will be the output we will get on the console if child div is clicked? 2 | Why the output was like that? 3 | 4 | ```html 5 | 6 | 7 | 8 | 9 | 29 | 30 | 31 |
32 | Grandparent 33 |
34 | Parent 35 |
36 | Child 37 |
38 |
39 |
40 | 62 | 63 | 64 | ``` -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Examples/README.md: -------------------------------------------------------------------------------- 1 | ### সকল উদাহরন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Examples/example1.md: -------------------------------------------------------------------------------- 1 | Event delegation takes advantage of event propagation. 2 | It allows the event listener to be set on a parent element, 3 | thus avoiding adding event listeners to all the elements. 4 | 5 | The event listener is set on a parent element which listens for click events. 6 | If parent element is clicked, the callback will compare 7 | event.target (element which was clicked) against a common property. 8 | This will be clear if we see the example below: 9 | 10 | ```html 11 | 12 | 13 | Event Delegation and Propagation 14 | 15 | 29 | 30 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 55 | 56 | 57 | ``` 58 | 59 | When a button or element is clicked, 60 | the listener of the parent element catches the bubbling event. 61 | 62 | If we click on Button 1, then the output will be: 63 | button 1 was clicked 64 | or if we click on the 'box1' div, output will be: 65 | Box 1 was clicked 66 | 67 | Here, using event delegation we dont need to add a 68 | click listener to every one of the elements like we saw 69 | in the previous topic. We just need to add a event listener 70 | to the parent div and by using event bubbling formula, we can access 71 | the clicked child element by using 'e.target' -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Examples/example2.md: -------------------------------------------------------------------------------- 1 | Another classic example of event delegation would be 2 | this example below, which we might use regularly. 3 | 4 | Suppose we have a div on which we have many input boxes. 5 | We want to convert specific input values to uppercase. --> 6 | 7 | ```html 8 | 9 | 10 | Event Delegation & Propagation 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 |
19 | 20 | 22 | 23 | 30 | 31 | 32 | ``` -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Examples/example3.md: -------------------------------------------------------------------------------- 1 | ইফেক্ট বুঝতে হলে প্রথমে এই HTML ফাইলটি আপনার ব্রাউজারে ওপেন করে মাউসের রাইট বাটন ক্লিক করে Inspect এ ক্লিক করুন। 2 | অতঃপর Console ট্যাবে ক্লিক করুন। এখন Event Bubbling ও Event Capturing কিভাবে হচ্ছে সেটা বুঝতে বক্সগুলোতে 3 | ক্লিক করে দেখুন। 4 | 5 | মনেকরি আমাদের কাছে নীচের কোড অনুযায়ী একটি HTML ফাইল আছে। 6 | 7 | ```html 8 | 9 | 10 | 11 | 12 | 13 | 14 | Event Delegation and Propagation 15 | 16 | 17 | 42 | 43 | 44 |

Event Delegation Example

45 |
46 |
47 | 48 |
49 | 50 | 51 |
52 | 53 | 54 | 55 | 60 | 61 | 62 | 63 | ``` 64 | এখন আমরা কোন বাটনের সাথে ক্লিক ইভেন্ট যুক্ত না করে সেন্ট্রালি তাদের কন্টেইনার 'btn-container' এর সাথে ইভেন্টটি যুক্ত করবো। একই সাথে কোন element বা button এ ক্লিক হচ্ছে সেটা দেখার জন্য আমরা উপরের কোডের জাভাস্ক্রিপ্টের ভিতরে নীচের কোড যুক্ত করবো। 65 | 66 | ```js 67 | btnConatiner.addEventListener('click', (e) => { 68 | console.log(e.target); 69 | }) 70 | ``` 71 | 72 | এখন আমরা 'btn-container' এর ভিতরে কোথায় ক্লিক করছি সেটা ব্রাউজারের console ট্যাবে খুব সুন্দর করে দেখতে পাবো। এখন আমরা চাইলে আমাদের ইচ্ছা মতো এটাকে কাজে লাগাতে পারি। এখানে আমরা বাটনের লেখা অনুযায়ী কাজ করার জন্য ইভেন্ট লিসেনারকে নীচের কোডের মতো করে লিখিঃ 73 | 74 | ```js 75 | btnConatiner.addEventListener('click', (e) => { 76 | console.log(e.target); 77 | 78 | if(e.target.id === 'green') { 79 | e.target.classList.add('btn', 'green'); 80 | } 81 | else if(e.target.id === 'blue') { 82 | e.target.classList.add('btn', 'blue'); 83 | } 84 | else if(e.target.id === 'purple') { 85 | e.target.classList.add('btn', 'purple'); 86 | } 87 | }) 88 | ``` 89 | 90 | এখন বাটনগুলোতে ক্লিক করে দেখো। আসলে 'btn-container' কিভাবে এই ক্লিক ইভেন্ট পাচ্ছে সেটা আগেই আমরা জেনেছি [event-capturing-and-bubbling](https://github.com/vivasoft-ltd/javascript-bootcamp/tree/main/basic/8.%20event-capturing-and-bubbling) পার্ট থেকে। এই ক্লিক ইভেন্টটি কিভাবে propagate হচ্ছে সেটা দেখতে চাইলে নীচের কোডের মতো করে ইভেন্ট লিসেনার যুক্ত করুন। 91 | 92 | ```js 93 | btnConatiner.addEventListener('click', (e) => { 94 | console.log(e.path); 95 | }) 96 | ``` 97 | 98 | এখন আশাকরি ইভেন্ট bubbling, propagation এবং delegation নিয়ে আর কোন সংশয় থাকবে না। 99 | হ্যাপি কোডিং ;) -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Interview Questions/README.md: -------------------------------------------------------------------------------- 1 | ### সকল ইন্টারভিউ এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Practices/README.md: -------------------------------------------------------------------------------- 1 | ### সকল প্রাকটিস এর প্রশ্ন এই ফোল্ডারে দেখা যাবে। 2 | -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/Practices/practice1.md: -------------------------------------------------------------------------------- 1 | 2 | How can we use only one addEventListener in this code to access any element? 3 | Use Event Delegation to solve this. 4 | 5 | ```html 6 | 7 | 8 | Event Delegation and Propagation 9 | 10 | 30 | 31 | 32 |
33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |
43 | 44 | 45 | ``` -------------------------------------------------------------------------------- /basic/9. event-delegation-and-propagation/README.md: -------------------------------------------------------------------------------- 1 | ### Event delegation and propagation 2 | 3 | ইভেন্ট delegation ইভেন্ট propagation পদ্ধতি ব্যবহার করে। ইভেন্ট delegation কীভাবে কাজ করে তা বোঝার জন্য, আমাদেরকে প্রথমে ইভেন্ট propagation বুঝতে হবে। 4 | 5 | 6 | ### Event propagation 7 | আপনি যখন নিম্নলিখিত HTML এর button টি ক্লিক করেনঃ 8 | 9 | ```html 10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | ``` 18 | 19 | একটি ক্লিক ইভেন্ট কতগুলি element এ ট্রিগার হয়? button টি নিজেই একটি ক্লিক ইভেন্ট পায়। কিন্তু এছাড়াও ঐ button এর সকল ancestors এবং এমনকি document ও window অবজেক্ট ক্লিক ইভেন্ট পায়। 20 | 21 | একটি ক্লিক ইভেন্ট 3টি পর্যায়ে প্রচারিত হয়: 22 | 1. Capture phase — window, document এবং root element থেকে শুরু করে ইভেন্ট টার্গেট এলিমেন্টের ancestor মধ্য দিয়ে নিচে নেমে যায়। 23 | 2. Target phase — ব্যবহারকারী যে element টিতে ক্লিক করেছেন তাতে ইভেন্টটি ট্রিগার হয়। 24 | 3. Bubble phase — অবশেষে, root element, document এবং window পর্যন্ত target element এর ancestor এর মাধ্যমে event টি bubble up হয়ে যায়। 25 | 26 | ![image](https://user-images.githubusercontent.com/712313/143814244-4e801a09-f50f-4d87-8503-2686d5f0f1db.png) 27 | 28 | নিম্নলিখিত ইভেন্ট হ্যান্ডলার element এ সংঘটিত ক্যাপচার পর্বে ক্লিক ইভেন্টের জন্য শোনে 29 | 30 | ```javascript 31 | document.body.addEventListener('click', () => { 32 | console.log('Body click event in capture phase'); 33 | }, true); 34 | ``` 35 | 36 | নিচের method এর তৃতীয় আর্গুমেন্ট হল `captureOrOptions` আপনাকে বিভিন্ন পর্যায় থেকে ইভেন্টগুলি ধরতে দেয়: 37 | 38 | ```javascript 39 | element.addEventListener(eventType, handler, [captureOrOptions]); 40 | ``` 41 | 42 | - যদি captureOrOptions argument টি missing, false বা { capture: false } হয়, তাহলে listener target এবং bubble phase এর event গুলি ক্যাপচার করে 43 | - যদি argument টি true হয় বা { capture: true } হয়, তাহলে listener ক্যাপচার পর্বের ঘটনাগুলি শোনে। 44 | 45 | তাহলে, কিভাবে ইভেন্ট propagation একাধিক button এর event ক্যাপচার করতে সাহায্য করে? 46 | অ্যালগরিদম টি সহজ: ইভেন্ট লিসেনারকে button এর parent এর সাথে সংযুক্ত করুন, এবং একটি button ক্লিক করা হলে bubble ইভেন্ট ধরতে হবে। ঠিক এভাবেই ইভেন্ট delegation কাজ করে। 47 | 48 | 49 | ### Event delegation 50 | আসুন একাধিক button এ ক্লিকগুলি ধরতে ইভেন্ট delegation ব্যবহার করি: 51 | 52 | ```html 53 |
54 | 55 | 56 | 57 | 58 |
59 | 67 | ``` 68 | 69 | 70 | 71 | ইভেন্ট delegation mechanism টি অনেক সহজ, ইভেন্ট listener দের সরাসরি button গুলিতে সংযুক্ত করার পরিবর্তে, আপনি parent element `
` -এ ইভেন্ট listen delegate করেন। যখন একটি ক্লিক করা হয়, তখন মূল element টির listener (parent element টির listener) bubble ইভেন্টটি ধরে। 72 | 73 | ইভেন্ট delegation ব্যবহার করার জন্য 3টি পদক্ষেপ প্রয়োজন: 74 | 75 | **Step 1. ইভেন্টগুলি ধরার জন্য element গুলির parent নির্ধারণ করুন**
76 | (উপরের উদাহরণে, `
` হল button গুলির parent element) 77 | 78 | **Step 2. ইভেন্ট listener কে মূল element এর সাথে সংযুক্ত করুন** 79 | `document.getElementById('buttons').addEventListener('click', handler)` 80 | ইভেন্টটি লিসেনারকে button এর parent element এর সাথে সংযুক্ত করে। এই listener button ক্লিকে প্রতিক্রিয়া দেখায় কারণ button ক্লিক ইভেন্ট ancestor এর মাধ্যমে bubble করে event propagation এর কারণে। 81 | 82 | **Step 3. target element নির্বাচন করতে event.target ব্যবহার করুন**
83 | যখন একটি button ক্লিক করা হয়, হ্যান্ডলার ফাংশন একটি event object argument এর সঙ্গে invoke হয়, event.target.property হল সেই element যার উপর ইভেন্টটি পাঠানো হয়েছে, যা উদাহরণে একটি button 84 | 85 | ```javascript 86 | .addEventListener('click', event => { 87 | if (event.target.className === 'buttonClass') { 88 | console.log('Click!'); 89 | } 90 | }); 91 | ``` 92 | 93 | `event.currentTarget` সেই element টিকে নির্দেশ করে যেখানে ইভেন্ট listener সরাসরি সংযুক্ত থাকে। উদাহরণে, `event.currentTarget` হল `
`। 94 | -------------------------------------------------------------------------------- /basic/README.md: -------------------------------------------------------------------------------- 1 | ## Table of contents 2 | 3 | 1. [Execution Context (এক্সিকিউশন কনটেক্সট)](1.%20execution-context) 4 | 2. [Scope (স্কোপ)](2.%20scope) 5 | 3. [Hoisting (হইস্টিং)](3.%20hoisting) 6 | 4. [Closure (ক্লোজার)](4.%20closure) 7 | 5. [Call by value and call by reference (কল বাই ভ্যালু এবং কল বাই রেফারেন্স)](5.%20call-by-value-and-call-by-reference) 8 | 6. [Callback & Higher-Order functions (কলব্যাক এবং হাইয়ার অর্ডার ফাংশন)](6.%20callback-and-higher-order-functions) 9 | 7. [This Keyword (দিস কিওয়ার্ড)](7.%20this-keyword) 10 | 8. [Event capturing and bubbling (ইভেন্ট ক্যাপচারিং এবং বাবলিং)](8.%20event-capturing-and-bubbling) 11 | 9. [Event delegation and propagation (ইভেন্ট ডেলিগেশন এবং প্রোপাগেশন)](9.%20event-delegation-and-propagation) 12 | 10. [Browser Storage and Caching (ব্রাউজার স্টোরেজ এবং ক্যাশিং)](10.%20browser-storage-and-caching) 13 | 11. [Debouncing and Throttling (ডিবাউন্সিং এবং থ্রোটলিং)](11.%20debouncing-and-throttling) 14 | 12. [Use Strict in JavaScript (ইউস স্ট্রিক্ট ইন জাভাস্ক্রিপ্ট)](12.%20use-strict) 15 | 13. [IIFE in JavaScript (আইআইএফই ইন জাভাস্ক্রিপ্ট)](13.%20iife-in-javascript) 16 | -------------------------------------------------------------------------------- /projects/README.md: -------------------------------------------------------------------------------- 1 | # VivaSoft JavaScript Bootcamp Projects 2 | 3 | This repository contains all the projects for VivaSoft Javascript Bootcamp. 4 | 5 | | # | Project | Live Demo | 6 | | :-: | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | 7 | | 01 | [Expanding Cards](https://github.com/vivasoft-ltd/javascript-bootcamp/tree/develop/projects/expanding-cards) | [Live Demo](https://blackbox47.github.io/expanding-cards/) | 8 | | 02 | [Big Bang](https://github.com/vivasoft-ltd/javascript-bootcamp/tree/develop/projects/big-bang) | [Live Demo](https://blackbox47.github.io/big-bang/) | 9 | | 03 | [Snake Eye](https://github.com/vivasoft-ltd/javascript-bootcamp/tree/develop/projects/snake-eye) | [Live Demo](https://blackbox47.github.io/snake-eye/) | 10 | | 03 | [Blurry Loading](https://github.com/vivasoft-ltd/javascript-bootcamp/tree/develop/projects/blurry-loading) | [Live Demo](https://blackbox47.github.io/blurry-loading/) | 11 | -------------------------------------------------------------------------------- /projects/big-bang/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Big Bang 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |

0

13 |

Points

14 | 16 |
17 |
18 | 19 | 20 |
21 | Score: 22 | 0 23 |
24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /projects/blurry-loading/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Blurry Loading 8 | 9 | 10 |
11 |
0%
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /projects/blurry-loading/script.js: -------------------------------------------------------------------------------- 1 | const loadText = document.querySelector('.loading-text') 2 | const bg = document.querySelector('.bg') 3 | 4 | let load = 0 5 | 6 | let int = setInterval(blurring, 30) 7 | 8 | function blurring() { 9 | load++ 10 | 11 | if (load > 99) { 12 | clearInterval(int) 13 | } 14 | 15 | loadText.innerText = `${load}%` 16 | loadText.style.opacity = scale(load, 0, 100, 1, 0) 17 | bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)` 18 | } 19 | 20 | const scale = (num, in_min, in_max, out_min, out_max) => { 21 | return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min 22 | } -------------------------------------------------------------------------------- /projects/blurry-loading/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Ubuntu'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Ubuntu', sans-serif; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | height: 100vh; 13 | overflow: hidden; 14 | margin: 0; 15 | } 16 | 17 | .bg { 18 | background: url('https://images.unsplash.com/photo-1657839368752-00f5f6dd8592?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80') 19 | no-repeat center center/cover; 20 | position: absolute; 21 | top: -30px; 22 | left: -30px; 23 | width: calc(100vw + 60px); 24 | height: calc(100vh + 60px); 25 | z-index: -1; 26 | filter: blur(0px); 27 | } 28 | 29 | .loading-text { 30 | font-size: 50px; 31 | color: #fff; 32 | } -------------------------------------------------------------------------------- /projects/expanding-cards/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Expanding Cards 8 | 9 | 10 |
11 |
12 |

Explore The World

13 |
14 |
15 |

Wild Forest

16 |
17 |
18 |

Sunny Beach

19 |
20 |
21 |

City on Winter

22 |
23 |
24 |

Mountains - Clouds

25 |
26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /projects/expanding-cards/script.js: -------------------------------------------------------------------------------- 1 | const panels = document.querySelectorAll('.panel') 2 | 3 | panels.forEach(panel => { 4 | panel.addEventListener('click', () => { 5 | removeActiveClasses() 6 | panel.classList.add('active') 7 | }) 8 | }) 9 | 10 | function removeActiveClasses() { 11 | panels.forEach(panel => { 12 | panel.classList.remove('active') 13 | }) 14 | } -------------------------------------------------------------------------------- /projects/expanding-cards/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Muli&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: 'Muli', sans-serif; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | height: 100vh; 13 | overflow: hidden; 14 | margin: 0; 15 | } 16 | 17 | .container { 18 | display: flex; 19 | width: 90vw; 20 | } 21 | 22 | .panel { 23 | background-size: cover; 24 | background-position: center; 25 | background-repeat: no-repeat; 26 | height: 80vh; 27 | border-radius: 50px; 28 | color: #fff; 29 | cursor: pointer; 30 | flex: 0.5; 31 | margin: 10px; 32 | position: relative; 33 | -webkit-transition: all 700ms ease-in; 34 | } 35 | 36 | .panel h3 { 37 | font-size: 24px; 38 | position: absolute; 39 | bottom: 20px; 40 | left: 20px; 41 | margin: 0; 42 | opacity: 0; 43 | } 44 | 45 | .panel.active { 46 | flex: 5; 47 | } 48 | 49 | .panel.active h3 { 50 | opacity: 1; 51 | transition: opacity 0.3s ease-in 0.4s; 52 | } 53 | 54 | @media (max-width: 480px) { 55 | .container { 56 | width: 100vw; 57 | } 58 | 59 | .panel:nth-of-type(4), 60 | .panel:nth-of-type(5) { 61 | display: none; 62 | } 63 | } -------------------------------------------------------------------------------- /projects/modal/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function Modal() {} 3 | 4 | Modal.prototype.open = function() { 5 | const modal = document.querySelector(".modal"); 6 | console.log("hello") 7 | modal.classList.add("modal--active") 8 | } 9 | 10 | Modal.prototype.close = function() { 11 | const modal = document.querySelector(".modal"); 12 | modal.classList.remove("modal--active") 13 | } 14 | 15 | document.addEventListener("DOMContentLoaded", function() { 16 | const modal = new Modal(); 17 | const openModal = document.querySelector("#openModal"); 18 | const closeModal = document.querySelectorAll(".modal__close"); 19 | 20 | openModal.addEventListener("click", function() { 21 | modal.open() 22 | }) 23 | 24 | closeModal.forEach(function(btnClose) { 25 | btnClose.addEventListener("click", function() { 26 | modal.close() 27 | }) 28 | }) 29 | 30 | 31 | 32 | }); 33 | })() 34 | 35 | -------------------------------------------------------------------------------- /projects/modal/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Modal || Vanilla JavaScript 11 | 12 | 13 | 14 | 15 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /projects/snake-eye/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Snake Eye 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /projects/snake-eye/index.js: -------------------------------------------------------------------------------- 1 | const canvas = document.querySelector("canvas"); 2 | canvas.width = innerWidth; 3 | canvas.height = innerHeight; 4 | 5 | let canvasW, canvasH; 6 | canvasW = canvas.width; 7 | canvasH = canvas.height; 8 | 9 | let eyes = [], 10 | delta, 11 | numberOfEyes = 300; 12 | const ctx = canvas.getContext("2d"); 13 | 14 | console.log(canvas); 15 | 16 | const mouse = { 17 | x: undefined, 18 | y: undefined, 19 | }; 20 | 21 | window.addEventListener("mousemove", function (e) { 22 | mouse.x = e.x; 23 | mouse.y = e.y; 24 | }); 25 | 26 | class Eye { 27 | constructor(eye) { 28 | this.x = eye.x; 29 | this.y = eye.y; 30 | this.radius = eye.radius; 31 | } 32 | draw() { 33 | ///// Eye 34 | ctx.fillStyle = "red"; 35 | ctx.beginPath(); 36 | ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); 37 | ctx.fill(); 38 | ctx.closePath(); 39 | 40 | ///// Get Angle between mouse and (Irish and Pupil) 41 | let dx = mouse.x - this.x; 42 | let dy = mouse.y - this.y; 43 | delta = Math.atan2(dy, dx); 44 | 45 | //// Irish 46 | let irish_x = this.x + Math.cos(delta) * (this.radius / 10); 47 | let irish_y = this.y + Math.sin(delta) * (this.radius / 10); 48 | let irish_radius = this.radius / 1.2; 49 | ctx.beginPath(); 50 | ctx.fillStyle = "white"; 51 | ctx.arc(irish_x, irish_y, irish_radius, 0, 2 * Math.PI, true); 52 | ctx.fill(); 53 | ctx.closePath(); 54 | 55 | //// Pupil 56 | let pupil_x = this.x + Math.cos(delta) * (this.radius / 2); 57 | let pupil_y = this.y + Math.sin(delta) * (this.radius / 2); 58 | let pupil_radius = this.radius / 2.5; 59 | ctx.beginPath(); 60 | ctx.fillStyle = "black"; 61 | ctx.arc(pupil_x, pupil_y, pupil_radius, 0, 2 * Math.PI); 62 | ctx.fill(); 63 | ctx.closePath(); 64 | 65 | //// pupil reflection 66 | ctx.beginPath(); 67 | ctx.arc( 68 | pupil_x - pupil_radius / 3, 69 | pupil_y - pupil_radius / 3, 70 | pupil_radius / 2, 71 | 0, 72 | 2 * Math.PI 73 | ); 74 | ctx.fillStyle = "rgba(255,255,255,0.1)"; 75 | ctx.fill(); 76 | ctx.closePath(); 77 | 78 | //// Mouse 79 | ctx.beginPath(); 80 | ctx.fillStyle = "gold"; 81 | ctx.arc(mouse.x, mouse.y, 25, 0, 2 * Math.PI); 82 | ctx.fill(); 83 | ctx.closePath(); 84 | } 85 | } 86 | 87 | function init() { 88 | eyes = []; 89 | for (let ind = 0; ; ind++) { 90 | if (eyes.length >= numberOfEyes) break; 91 | let eye = { 92 | radius: Math.floor(Math.random() * 100 + 5), 93 | x: Math.random() * canvasW, 94 | y: Math.random() * canvasH, 95 | }; 96 | let flag = 0; 97 | for (let i = 0; i < eyes.length; i++) { 98 | let previousEye = eyes[i]; 99 | let dx = previousEye.x - eye.x; 100 | let dy = previousEye.y - eye.y; 101 | let distance = Math.sqrt(dx * dx + dy * dy); 102 | if (distance < previousEye.radius + eye.radius) { 103 | flag = 1; 104 | break; 105 | } 106 | } 107 | if (flag === 0) eyes.push(new Eye(eye)); 108 | } 109 | console.log(eyes); 110 | } 111 | 112 | function animate() { 113 | requestAnimationFrame(animate); 114 | ctx.clearRect(0, 0, canvasW, canvasH); 115 | for (let i = 0; i < eyes.length; i++) { 116 | eyes[i].draw(); 117 | } 118 | } 119 | 120 | window.addEventListener("resize", function (e) { 121 | canvas.width = innerWidth; 122 | canvas.height = innerHeight; 123 | init(); 124 | }); 125 | 126 | init(); 127 | animate(); 128 | --------------------------------------------------------------------------------