# Inteview question Javascript 1.0 ( 0 -> 50 ) **CỰC KỲ QUAN TRỌNG, BẮT BUỘC ÔN TRƯỚC KHI PV** **Cách được đánh giá cao khi trả lời câu hỏi** 1. Trả lời 2. Giải thích 3. Đưa giải pháp tương tự 4. So sánh vì sao mình chọn cái này không chọn cái khác - Không nên để người pv chen vào, hãy tự trả lời hết 1 cách tự tin, vì bạn đã học hết rồi đừng sợ gì nữa. - Ví dụ câu hỏi sẽ dạng ntn "Em hiểu gì về OOP" thay vì "OOP gồm mấy tính chất" để xem ta trả lời ntn, có học rộng hiểu sâu k :)) [-> Trả lời câu 16](#16-Các-tính-chất-của-hướng-đối-tượng-OOP) ### 0. Stack, queue là gì*** Khái niệm này cũng có liên quan đến nhiều lĩnh vực như logistic ![lifo](https://hackmd.io/_uploads/HJ-SveoV6.jpg) ---- **LIFO: last in, first out - vào sau, ra trước.** --> STACK ![liffo](https://hackmd.io/_uploads/rkiPOloNT.jpg) ---- **FIFO: first in, first out - vào trước, ra trước.** --> QUEUE ![fifio](https://hackmd.io/_uploads/B1ODOgs46.jpg) ![](https://images.viblo.asia/494c4935-fc7f-4032-a5f7-b7142d85b96c.png) Đọc thêm: https://viblo.asia/p/xay-dung-stack-va-queue-bang-javascript-ORNZqB4el0n ### 1. Scope là gì ? Scope là ++phạm vi hoạt động++ của 1 biến + 3 loại chính + Global scope + Function scope ( class scope ) + Block scope ( local scope ) **Global scope**: là 1 biến được khai báo nằm ngoài phạm vi của function. **Function scope** : là 1 biến được khai báo nằm trong phạm vi của function. **Block scope** : là phạm vi bên trong if esle while do **1. Lexcial scope** ```javascript function outerFunction() { const x = 10; function innerFunction() { console.log(x); } innerFunction(); } outerFunction(); ``` // innerFunction có thể truy cập biến x // của outerFunction gọi là lexical scope **2. Scope chain** Có thể hiểu là các func lồng nhau như xiềng xích. Func C bên trong có thể truy cập ra biến bên ngoài nó. ```javascript let a = 10; function A(){ function B(){ function C(){ console.log(a); //10 } } } ``` ### 2. Method bind() call() apply(). **a. Method bind** - Phương thức bind() cho phép ràng buộc this cho 1 phương thức. - Phương thức bind() sẽ trả về một hàm mới với context được bind và không gọi hàm. - Hàm được trả về từ bind() vẫn có thể nhận các đối số của hàm gốc. - Ưu tiên hơn khi truyền đối số trong bind(thisAgr,arg1,arg2) **b. Method call** - Gọi hàm và bind this tới đối tượng khác, mặc định this là window object - Không trả ra hàm mới, nó gọi luôn hàm sau khi bind this (Fn.bind()) thì chỉ bind this nhưng không gọi hàm) - Fn.call() dùng để mượn hàm - func borrowing - Fn.call() có thể dùng để kế thừa properties & method từ Constructor khác **c. Method apply** - Tương tự call nhưng truyền đối số bằng array thay vì string ### 3. Con trỏ this là gì ? - Dùng để tham chiếu đến instance hiện tại hoặc hàm hiện tại hoặc object 1. Function ```javascript var myFunc = function(){ console.log(this) //Gobal-> Window {window: Window {...}, self: Window ...} function inner(){ console.log(this) // Global -> Window } inner(); setTimeout(function(){ console.log(this) // Global -> Window },1000); } myFunc(); ``` 2. Function ở strict mode ```javascript "use strict" function test(){ console.log(this) // undefined } test() ``` 3. Object ```javascript var myObject = {}; myObject.myMethod = function(){ console.log(this) // Object -> {myMethod: function()} } myObject.myMethod(); ``` 4. DOM ```javascript var header = document.getElementById('header'); var toggleHeaderMobile = function(){ console.log(this) // element -> <header></header> } ``` 5. Method ```javascript const person = { firstName : "Huy", lastName : "Pham Gia", getFullName : function () { return this.lastName + " " + this.firstName; } } console.log(person.getFullName()) // Pham Gia Huy ``` 6. Lưu ý : Arrow function không có con trỏ this **Quan trọng khác về con trỏ this, 100% sẽ được hỏi** **Call, bind, apply.** 1. Call. ```javascript! const person1 = { name: "Huy", surname: "Pham", sayName: function () { return this.name + " " + this.surname; } } const person2 = { name: "Tuam", surname: "Trang" } console.log(person1.sayName.call(person2)) // Tuam Trang ``` 2. Apply ```javascript! const person1 = { name: "Huy", surname: "Pham", sayName: function (city, country) { return this.name + " " + this.surname + " " + city + " " + country; } } const person2 = { name: "Tuam", surname: "Trang" } console.log(person1.sayName.apply(person2, ['TPHCM', 'Viet Nam'])) // 'Tuam Trang TPHCM Viet Nam' ``` 3. Bind ```javascript! const person1 = { name: "Huy", surname: "Pham", sayName: function (city, country) { return this.name + " " + this.surname; } } const person2 = { name: "Nguyễn", surname: "Cải" } const sayPerson2 = person1.sayName.bind(person2) console.log(sayPerson2 // "Nguyễn Cải" ``` ### 4. Javascript có mấy kiểu khai báo hàm ? Có 3 kiểu 1. Declaration function ```javascript function test(){} ``` 2. Expression function ```javascript const test = function(){} ``` 3. Arrow function ```javascript const test = () => {} ``` Anonymous function không tính là 1 kiểu khai báo IIFE gọi hàm chạy ngay lập tức ```javascript! (()=>{ console.log('hello world') })() ``` ### 6. Browser xử lý Javascript như thế nào ? - Tải web dựa vào URL - Phân tích HTML,CSS tạo DOM (document object model) và CSSOM (CSS object model) - Tìm và tải tệp javascript sau đó thực thi chúng nhờ JSVM (Javascript virtual machine) - Quản lý bộ nhớ (memory management), JSVM sẽ quản lý object trong javascript giải phóng khi không dùng nữa. Nhờ Garbage collection. ### 7. Sự khác nhau của var, const và let : - var : - ES5 - Có cơ chế hoisting - Phạm vi global scope và function scope - const, let : - ES6 - Không có cơ chế hoisting - Phạm vi là block scope let : trong cùng 1 phạm vi không thể khai báo lại biến. const : thì không thể gán lại biến cho giá trị khác. ==Trường hợp đặc biệt== Object và array có thể gán được là do <a href="#-Bộ-nhớ-trong-Javascript" >bộ nhớ.</a> ### 8. Có cách nào thay đổi giá trị của const không ? Tại sao ? Có. Tìm hiểu về <a href="#-Bộ-nhớ-trong-Javascript" >bộ nhớ.</a> 1. Object ```javascript const person = { name :"HUY", age:12 } person.name = "Tuấn" console.log(person) // {name: "Tuấn", age: 12} ``` 2. Array ```javascript const array = [1,2,3,4]; array[0] = 5; console.log(array) ``` ### 9. Arrow function khác gì với function thường ? Arrow function ko làm thay đổi ngữ cảnh con trỏ this, k bind argument, k hoisting, k làm method, k phù hợp làm constructor, k có prototype và ngắn gọn hơn. ### 10. ES6 có tính năng gì mới ? Kể tên 1. Arrow function 2. const let 3. class & import export module 4. promise, async await 5. for in, for of 6. Enhance object literal - Value properties shorthand - Computed key - Method definition shorthand 7. Default parameter & rest parameter 8. Spread operator 9. Destructuring assigment 10. Template string - multiline string ### 11. Kể tên HOF (high order function) trong ES6: map, filter, reduce, some, every, sort, forEach, find, findIndex,... ### 12. Tại sao gọi là HOF ? HOF (high order function) có 1 trong 2 đặc điểm sau : 1. Nhận một hoặc nhiều hàm khác làm tham số đầu vào (đôi khi được gọi là callback functions). 2. Return 1 hàm mới ### 13. Closure, currying và callback function* **Closure** là cơ chế cho phép hàm bên trong truy cập được biến bên ngoài nó, dù hàm bên ngoài nó đã thực thi. ```javascript function outerFunction() { const x = 10; function innerFunction() { console.log(x); } return innerFunction; /* cách viết khác return function innerFunction() { console.log(x); } */ } const closureFnc = outerFunction(); // closureFunc là 1 closure function closureFnc(); // 10 ``` **Currying** cách viết chia hàm và có sử dụng closure function ```javascript const add = (x,y,z) => x + y + z; function add(x) { return function(y) { return function(z){ return x + y + z; } }; } // cách viết khác arrow func const add = x => y => z => x + y + z console.log(add(1)(2)(3)) // 6 ``` **Callback** là 1 function A truyền vào 1 function B dưới dạng tham số, function B gọi là callback func ```javascript function fetchData(callback) { // Giả định là đây là một công việc bất đồng bộ, lấy dữ liệu từ máy chủ setTimeout(function() { const data = { name: 'John', age: 30 }; callback(data); // Gọi lại hàm callback khi công việc hoàn thành }, 1000); } function processData(data) { console.log(`Name: ${data.name}, Age: ${data.age}`); } fetchData(processData); // Gọi fetchData với callback processData ``` ### 14. Spread operator là gì ? clone [...array] {...object} {...object, key : value} ### 15. Promise, async await là gì ? Promise cho phép thực thi tác vụ bất đồng bộ (asynchronous). Nhận vào 1 function (excutor function) 2 tham số resolve và reject. 3 trạng thái : fullfill, pending và rejected **1. Promise** ```javascript const myPromise = new Promise((resolve, reject) => { setTimeout(() => { // do something }, 1000); }); myPromise .then((result) => { console.log("Promise resolved with value:", result); }) .then((result) => { console.log("Promise resolved with value:", result); }) .catch((error) => { console.error("Promise rejected with error:", error); }); ``` **2. Async/ await** ```javascript async function getUserData() { try { const userData = await fetchUserData(); console.log("User data:", userData); } catch (error) { console.error("Error fetching user data:", error); } } getUserData(); ``` Được tạo ra tránh tình trạng callback hell ### 16. Các tính chất của hướng đối tượng OOP **1. Abstraction - tính trừu tượng** > - Con người có màu tóc, màu mắt, màu da, số điện thoại, trường, số CMND, tên tuổi… > - Xây dựng 1 app tính tiền lương nhân viên, ta sẽ ++trừu tượng++ hóa chỉ dùng thuộc tính quan trọng vào : số CMND, tên, tuổi, bằng ielts + 2 củ, bằng toeic + 500k... **2. Inheritance - tính kế thừa** > Class cha có thuộc tính và phương thức gì. Class con sẽ có y lại mấy cái đó **3. Polymorphism - tính đa hình** > - Đa hình nghĩa là có nhiều hình khác nhau. Trong lập trình ta có thể hiểu là các hàm có cùng tên nhưng cách hoạt động chúng khác nhau. > - Như hàm `makeSound()` con vịt kêu `quác quác` còn con mèo kêu `mew mew` > - Có 2 loại thể hiện trong tính đa hình overload và override > - Overload : trong 1 class, cùng tên hàm nhưng hàm 2 tham số hoạt động kiểu khác, 3 tham số kiểu khác... > - Override : sẽ luôn đi kèm với tính kế thừa. Class con sẽ ghi đè dc phương thức của class cha. **4. Encapsulation** > - Ẩn những dữ liệu nhạy cảm như password. Các class khác sẽ ko thể đọc dc dùng từ khóa `private`. Nếu có nhu cầu thay đổi giá trị của field, thì ta sẽ public property để cho phép get hoặc set field ### 17. Có 3 promise đang chạy, nếu muốn chờ xong cả 3 thì phải làm gì ? promise.all ### 18. Dự án trước em làm về gì ? Em cảm thấy gì khó nhất ? Form ### 19. JSON là gì ? JSON (javascript object notation) là định dạng dữ liệu với dung lượng nhẹ dùng để truyền tải dữ liệu khi xây dựng phần mềm. Value chỉ được sử dụng 6 loại sau : `number` `string` `null` `boolean` `array` `object` Value k lưu được : `date` `undefined` và `function` Định dạng nhấy đôi, key value Mã hóa encode và decode JSON.stringify & JSON.parse ### 20. HTTP Status code : 200 : ok 400 : bad request - lỗi cú pháp từ FE 403 : Forbidden - user bị cấm truy cập ko đủ quyền 404 : Not found 405 : Method not allow 500 : internal server error 503 : service unvailable - máy chủ quá tải 505 : HTTP version not supported ### 21. Sử dụng gì để call API ngoài axios ? XHR ( XML http request ) fetch và ajax ### 22. Thứ tự in đúng là gì ? ```javascript setTimeout(()=>console.log("a"),200); setTimeout(()=>console.log("b"),0); console.log(c) ``` Đáp án : ```javascript c b a ``` ### 23. object.Prototype & propto ( getPrototype và setPrototype ) ```javascript= const animal = { eats: true } const rabbit = { jumps: true } rabbit.__proto__ = animal; console.log(Object.getPrototypeOf(rabbit)) // { eats: true } ``` ```javascript= const animal = { eats: true } const rabbit = { jumps: true } Object.setPrototypeOf(rabbit,animal); console.log(Object.getPrototypeOf(rabbit)) // { eats: true } ``` ### 24. AJAX là gì ? AJAX ( Asynchronous javascript and XML) là 1 công nghệ giúp chúng ta tạo ra trang web động mà không cần reload lại trang. Giảm tải server = cách giảm số lần reload trang Tăng trải nghiệm người dùng Viết bằng JS, mỗi user chạy độc lập không ảnh hưởng đến nhau ### 26. RESTful API là gì ? Representational state transfer là 1 kiểu thiết kế API được sử dụng để tạo ra các dịch vụ web Nó cho phép các ứng dụng giao tiếp với nhau thông qua giao thức HTTP sử dụng các phương thức HTTP như GET, POST, PUT, DELETE... để thao tác CRUD với tài nguyên trên server ### 27. API là gì ? Application programming interface là 1 tập hợp các qui tắc, giao thức và công cụ cho phép các ứng dụng phần mềm khác nhau giao tiếp và tương tác với nhau 1 cách đơn giản và hiệu quả nhất ### 28. Các kiểu dữ liệu cơ bản trong JS ? Tham trị và tham chiếu Có 8 kiểu - 7 kiểu primities type ( nguyên thủy, tham trị ) : - number - string - undefined - null - symbol - bigInt - boolean - 1 kiểu reference type ( tham chiếu ) : object ( array về cơ bản cũng là object ) ```javascript let arr =[] console.log(typeof arr) // Object ``` **Câu hỏi thường đc hỏi** ```javascript! const member = { name: "Huy", address: { street: "Nguyễn Huệ" } } const member2 = { ...member } member.name = "Tuan" member.address.street = "Trương Định" console.log(member) console.log(member2) ``` :::spoiler Đáp án ```javascript! console.log(member) // { name: "Tuan", address: { street: "Trương Định" } } console.log(member2) // { name: "Huy", address: { street: "Trương Định" } } ``` ::: Lí do ? -> Đọc lại [Câu 33](https://hackmd.io/Ky0nXIklSZudMUty2Kawbw?both#33-B%E1%BB%99-nh%E1%BB%9B-trong-Javascript) ### 29. Falsy gồm những giá trị nào ? 1. undefiend 2. null 3. "" 4. false 5. 0 6. NaN **Dễ mắc lỗi arr và object** ```javascript! gọi API lấy được data là 1 array const productList = [] if(productList){ // sai hoàn toàn vì nó luôn true (dù có data hay k) console.log('nếu có data thì thực thi xử lý gì đó'); } if(productList.length > 0){ // nên check length console.log('nếu có data thì thực thi xử lý gì đó'); } ``` Trường hợp productList là 1 object cũng tương tự array nó ko nằm trong falsy. ```javascript! const product = { age: "32" } // có nhiều cách, biết 1 trong số đó là dc if(Object.entries(product).length > 0){ console.log('1') } ``` ### 30. Localstorage, sessionStorage và cookie - LocalStorage : lưu vĩnh viễn trên trình duyệt, dung lượng 5-10MB, các trang khác ko thể truy cập đến LocalStorage nếu như khác domain. - SessionStorage : y chang local, nhưng dữ liệu chỉ lưu trong 1 phiên làm việc, đóng tab là mất data. > ví dụ : localStotage.setItem() | sessionStorage.setItem() - Cookie : ko phải là web storage, thời gian lưu trữ có giới hạn khi hết hạn cookie sẽ tự động xóa. Dung lượng chỉ có 4KB ### 31. Đáp án Tìm hiểu về marcro, micro. Promise (micro) ưu tiên chạy hơn setTimeout(marcro) ```javascript= console.log("start"); const promise1 = Promise.resolve().then(()=>{ console.log("promise1"); const timer2 = setTimeout(()=>{ console.log("timer2") },0) }) const timer1 = setTimeout(()=>{ console.log("timer1"); const promise2 = Promise.resolve().then(()=>{ console.log("promise2") }) },0) const timer3 = setTimeout(()=>{ console.log("timer3"); const promise3 = Promise.resolve().then(()=>{ console.log("promise3") }) },0) console.log("end"); ``` Code đồng bộ chạy trc -> code bất đồng bộ ( gồm micro và marcro ) ưu tiên micro hơn marcro :::spoiler Đáp án ```javascript= start // synchronous - đồng bộ end // synchronous - đồng bộ promise1 timer1 promise2 timer3 promise3 timer2 ``` ::: ### 32. So sánh thông dịch và biên dịch Thông dịch (interpreter) Biên dịch (compiler) | | Compiler | Interpreter | | -------- | -------- | -------- | | Input | Toàn bộ code | 1 dòng code | | Output | Mã đối tượng trung gian | Không tạo ra đối tượng trung gian | | Cơ chế hoạt động | Biên dịch toàn bộ code rồi thực thi | biên dịch và thực thi đồng thời | | Tốc độ | Nhanh hơn | Chậm hơn | | Bộ nhớ | Nhiều hơn vì có MDTG | ít hơn | | NNLT | Java, C, C++,C# | Javascript, python, PHP| ==NOTE== : Trong quá trình phát triển phần mềm NNLT thông dịch Javascript sẽ nhanh hơn, sửa 1 dòng code -> refresh page -> code đã cập nhật Sửa 1 dòng code NNLT biên dịch Java sẽ tắt app, run build lại app toàn bộ chương trình. ### 33. Bộ nhớ trong Javascript | Cấp phát tĩnh | Cấp phát động | | -------- | -------- | | Kích thước phải biết tại thời điểm biên dịch | Kích thước có thể không biết tại thời điểm biên dịch | | Kiểu dữ liệu primitives type | KDL tham chiếu reference type | | Được giao cho Stack memory | Heap memory | | LIFO | Không có thứ tự cụ thể | > ==Ví dụ dễ hiểu== : LIFO (Last In, First Out) – nhập sau, xuất trước. Ngược lại, phương pháp này có nghĩa là các hàng hoá gần đây nhất được nhập vào kho sẽ được xuất ra đầu tiên. Các hàng hoá mới được sử dụng trước, dùng ưu tiên hơn hàng hoá cũ. ![image alt](https://felixgerschau.com/static/b452488bd7eeac0405c48f164da6280d/5a190/stack-heap-pointers.png) ![image alt](https://felixgerschau.com/static/87b4e1eb66afc84d49da13af8e897367/5a190/garbage-collectoion-algorithm.png)*dasdas* ### 34. Một số cách xử lí mảng trong javascript 1. map 2. filder 3. reduce 4. sort 5. find 6. findIndex 7. concat 8. join 9. shift 10. unshift 11. push ### 35. map và forEach khác nhau cái j ? - hàm map có trả về giá trị cho từng phần tử trong array. Thường dùng để trả về đoạn lặp nào đó. như project card chẳng hạn - hàm forEach ko có trả về giá trị như hàm map. Nó chỉ lướt qua từng phần tử ### 36. Sự khác nhau giữa class và object : Class nó như 1 bản vẽ khung xe hơi vậy có màu sắc, loại bánh xe, loại nội thất Object là cái được tạo ra từ cái bản vẽ khung xe đó có nhiều loại như + Xe màu cam, bánh to, nội thất da + Xe màu hồng, bánh nhỏ, nội thất vải + Xe màu tím, bánh vừa, nội thất chống đạn,... ```javascript= class Person { // viết hoa chữ cái đầu có constructor constructor(name,age){ this._name = name; this._age = age; } static randomNum(){ return Math.floor(Math.random()*100) } } const student = new Person("Huy",12) // về static Person.randomNum(); // đúng const student2 = new Person("Huy2",122) student2.randomNum(); // sai ``` ### 37. Vòng lặp nào làm thay đổi giá trị ban đầu, vòng lặp nào thì không*** + Vòng lặp for cho phép thay đổi giá trị trong mảng ```javascript! const numbers = [1, 2, 3, 4, 5]; for (let i = 0; i < numbers.length; i++) { numbers[i] = numbers[i] * 2; // Thay đổi giá trị của phần tử } console.log(numbers); // Mảng numbers bị thay đổi Kết quả : [2, 4, 6, 8, 10] ``` + Hàm forEach không thay đổi giá trị ban đầu của mảng. Nó chỉ cho phép bạn thực hiện một hành động cụ thể trên mỗi phần tử trong mảng, nhưng không thể trực tiếp thay đổi giá trị của phần tử đó trong mảng. ```javascript! const numbers = [1, 2, 3, 4, 5]; numbers.forEach((num, index, array) => { array[index] = num * 2; // Không thay đổi giá trị của phần tử }); console.log(numbers); // Mảng numbers không thay đổi ``` Kết quả : [1, 2, 3, 4, 5] ### 38. SOLID là gì https://www.youtube.com/watch?v=ft0ZpgKimgU&list=PLqfkD788zZGDz7XrEKiHxgUkEbHOg2ugq&index=11 1. Là từ viết tắt của 5 nguyên lí cơ bản - principle (nguyên tắc) 2. S (Single responsibility principle) : 1 class chỉ nên giữ 1 và chỉ 1 trách nhiệm duy nhất > Ví dụ : 1 class hóa đơn làm 3 công việc : tính thuế, in hóa đơn, gửi email tới người dùng. Thay vì 1 class làm hết tất cả nhiệm vụ này, tách ra 1 class Email để sendEmail. class Tax để caculateTax. 3. O (Open closed principle) : 1 class hoặc 1 function có thể thoải mái mở rộng nhưng cần hạn chế việc sửa đổi bên trong nó. > Ví dụ : cài thư viện,extension, add on cho google chrome. Dev k động vào source code của chrome. Mà chỉ viết thêm. 4. L (liskov subsitution principle) : các đối tượng của class con có thể thay thế các đôi tượng của class cha mà ko làm thay đổi tính đúng đắn của chương trình. > Ví dụ : ta có 1 class Bird có phương thức bay. Và 1 class Đại bàng, 1 class Chim cánh cụt. Ta nên tạo ra 1 class nữa là class Bird và 1 class chim biết bay. ### 39. Sự khác biệt giữa null và undefined, is not defined ?? Fact: câu này có thể người ta chỉ hỏi về null và undefined. ```javascript! let a = null; let b = undefined; let b; // chỉ mới khai báo chứ chưa gán giá trị c is not defined sayName() is not defined ``` - biến a có giá trị là rỗng - biến b được gán giá trị undefined nghĩa khác nữa là nó ko đc gán giá trị nào nên là undefined - c là chưa định khai báo biến c và định nghĩa hàm sayName() bao giờ ===> is not defined :::info **ĐỌC THÊM** [Tại sao null typeof là object mà nó ko phải là reference type, lại là primitive type ?](https://hackmd.io/fPaK8KuUQPy_FiLWMuPXyw#T%E1%BA%A1i-sao-nullprimitive-type-typeof-l%E1%BA%A1i-l%C3%A0-object-m%C3%A0-n%C3%B3-ko-ph%E1%BA%A3i-l%C3%A0-reference-type-) ::: ### 39.1 So sánh == và === giữa null và undefined ```javascript! let a = null; let b; console.log(a == b) // true console.log(a === b) // false ``` Lí do: === so sánh cả kiểu dữ liệu, mà kiểu dữ liệu của 2 thằng là khác nhau ```javascript! console.log(typeof a) // object console.log(typeof b) // undefined ``` ### 40. Ý nghĩa 3.2.2 của 1 phần mềm ? Major minor patch ### 41. == và === khác nhau cái gì ? == so sánh không cần kiểu dữ liệu === so sánh có kiểu dữ liệu ```javascript! 1 == '1' // true 1 === '1' // false ``` ### 42. Hoisting là gì ? Hoisting là cơ chế trong javacsript cho phép các biến hoặc hàm được khai báo ở đầu phạm vi của chúng trước khi thực thi đoạn code. ```javascript a = 1 var a; // khai báo var có hoisting abc() // declaration func có cơ chế hoisting function abc(){ console.log('321') } ``` Vì javascript không có 1 quy tắc "chuẩn" của 1 ngôn ngữ lập trình nên ES6 được ra đời để hạn chế nhược điểm này, const,let, arrowfunction... Không nên dùng var ```javascript! b = 1; let b; // const và let không làm được do ko có hoisting --> Cannot access 'b' before initialization // ko thể truy cập b trước khi khởi tạo bcd() // arrow func ko hỗ trợ -> báo lỗi const bcd = () =>{} express() // tương tự arrowfunction const express = function(){} ``` Viết đúng, khai báo trước khi xài ```javascript! let b; b = 1; const bcd = () =>{} bcd() const express = function(){} express() ``` ### 43. Sự khác nhau của GET và POST? ### 44. Sự khác nhau của SESSION và COOKIES? ### 45. Cách clone 1 object có method là function!!! Dùng đệ quy, khả năng cao sẽ bắt mình live coding, gõ câu 2.c là pass **1. Shalow clone** 2 cách dưới đây clone được cả method a) Với Object.assign: ```javascript! const original = { number: 1, method: function() { console.log(this.number); } }; const clone = Object.assign({}, original); clone.number = 2; clone.method(); // Outputs: 2 ``` b) Với spread operator ```javascript! const original = { number: 1, method: function() { console.log(this.number); } }; const clone = { ...original }; clone.number = 2; clone.method(); // Outputs: 2 ``` **2. Deep clone** a) stringify, parse(clone nhiều cấp nhưng ko có method) ```javascript! const original = { number: 1, method: function() { console.log(this.number); } }; // This will NOT copy the method const clone = JSON.parse(JSON.stringify(original)); ``` b) Dùng lodash ```javascript! const _ = require('lodash'); const original = { number: 1, method: function() { console.log(this.number); } }; const clone = _.cloneDeep(original); ``` c) Code tay ko dùng thư viện ```javascript! function cloneDeep(obj) { // Nếu obj không phải là một object hoặc là null, trả về chính nó (vì nó không thể clone) if (typeof obj !== 'object' || obj === null) { return obj; } // Tạo một instance mới nếu obj là một Array hoặc là một Object let cloneObj = Array.isArray(obj) ? [] : {}; // Duyệt qua mọi property trong obj for (let key in obj) { // Kiểm tra xem property có phải của obj không (không phải là property kế thừa) if (obj.hasOwnProperty(key)) { // Nếu giá trị của property là một object, clone đệ quy // Còn không, chỉ đơn giản là sao chép giá trị cloneObj[key] = typeof obj[key] === 'object' ? cloneDeep(obj[key]) : obj[key]; } } return cloneObj; } // Ví dụ sử dụng const original = { number: 1, method: function() { console.log(this.number); }, inner: { text: 'This is a nested object', } }; const cloned = cloneDeep(original); cloned.number = 2; // Thay đổi này không ảnh hưởng đến 'original' cloned.inner.text = 'Changed'; // Thay đổi này không ảnh hưởng đến 'original' cloned.method(); // Outputs: 2 ``` :::warning **Lưu ý function cloneDeep() trên** - Không xử lý các đối tượng như Date, RegExp, Map, Set, Blob, File, FileList, ImageData, ArrayBuffer, DataView, và các TypedArray. - Không xử lý các tham chiếu vòng lặp (cyclic references). - Không bảo toàn các thuộc tính non-enumerable và các symbol. ::: :::success Giải pháp ---> xài lodash cho lẹ ::: ### 46. Webpack là gì ? - Webpack là 1 tool chạy trên môi trường Node.JS giúp chúng ta đóng gói các file js, css, sass, img,... Ngoài ra webpack còn giúp chúng ta tạo ra 1 server ảo để thuận tiện cho việc code. ### 47. Spread operator & rest parameter Rest parameter được sử dụng trong declarations func và destructuring assignments. **Case 1:** Declaration func ```javascript! function sum() { console.log(arguments) // { [Iterator] 0: 1, 1: 23, 2: 4 } } const sum = () => console.log(arguments) // ko nhận được các biến sum(1, 23, 4); // Dùng rest parameters const sum = (...numbers) => { console.log(numbers) // [ 1, 432, 543 ] } sum(1, 432, 543) ``` **Case 2:** Destructuring assignment ( array và object ) ```javascript! const [first, ...rest] = [1, 2, 3, 4]; console.log(rest); // outputs [2, 3, 4] const { myName, ...rest } = { myName: 'huy', age: 12, address: { street: "Nguyễn huệ" } } console.log(myName) // huy console.log(rest) // { age: 12, address: { street: 'Nguyễn huệ' } } ``` Spread operator **Case 1:** ```javascript! const numbers = [1, 2, 3]; console.log(...numbers); // 1 2 3 ``` **Case 2:** ```javascript! const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3 }; console.log(obj2); // { a: 1, b: 2, c: 3 } ``` :::info Rest: làm parameter cho function VÀ trong destructuring assigment Spread operator: clone copy object và array ::: ### 48. Object.prototype & proto (ví dụ with getPrototypeOf, setPrototypeOf) ```javascript! ES5 function Person(){ this.name = 'huy' } Person.prototype.sayHello = () =>{ console.log('hello there') } const p = new Person(); console.log(p.name) // huy p.sayHello(); // hello there ``` ```javascript! ES6 class Person{ constructor(){ this.name = 'huy' }; sayHello(){ console.log('hello there') } } const p = new Person(); console.log(p.name) p.sayHello(); ``` ### 49. Optional chaining là gì ? ```javascript! const person = { name: "huy", age: 12, city: { street: "Nguyễn Huệ" } } const streetOfUser = person?.city?.street; const getPlace = person?.getPlace?.(); console.log(getPlace) // undefinfed ``` ### 50. Nullish Coalescing là gì ? nú lịt khô ẹc lé sing ```javascript! const user = { age: 0 } const ageOfUser = user.age || 18; console.log(ageOfUser) // 18 ``` Nhưng trường hợp tuổi cần là số 0 thì phải làm gì ? ```javascript! // check nếu là null || undefined sẽ lấy giá trị 18 const ageOfUser = user.age ?? 18; console.log(ageOfUser) // 0 ``` - Falsy gồm 6 giá trị: - 1. undefined* - 2. null* - 3. "" - 4. 0 - 5. false - 6. NaN Trừ undefined và null ra thì 4 giá trị falsy còn lại nó vẫn lấy được.