</>
⌕
← Trang chủ
JS

JavaScript

Closure, event loop, this, prototype, async

🃏 Ôn bằng flashcard
Tiến độ0/21 · 0%
Junior

`==` và `===` khác nhau thế nào? Type coercion hoạt động ra sao?

`===` so sánh giá trị và kiểu, không ép kiểu. `==` ép kiểu (type coercion) theo quy tắc phức tạp trước khi so sánh nên cho kết quả khó đoán, ví dụ `[] == false` là true. Mặc định dùng `===`; chỉ `x == null` là cách viết gọn hợp lý cho null và undefined.

#coercion#equality#truthy-falsy
Junior

Closure trong JavaScript là gì?

Closure là hàm "nhớ" được biến ở phạm vi (scope) nơi nó được tạo ra, kể cả khi hàm cha đã chạy xong.

#scope#function
Junior

Destructuring, spread và rest operator khác nhau thế nào?

Destructuring bóc giá trị từ array/object vào biến (hỗ trợ default, đổi tên). Spread `...x` mở rộng iterable/object thành phần tử rời; rest `...x` ở vế nhận gom phần còn lại thành array/object. Spread chỉ copy nông (shallow).

#es6#destructuring#spread
Junior

Khác nhau giữa var, let và const?

var có function scope và bị hoist (giá trị undefined); let/const có block scope và nằm trong Temporal Dead Zone trước khi khai báo; const không cho gán lại biến.

#scope#hoisting
Junior

map, filter, reduce dùng thế nào? Method nào của Array làm thay đổi mảng gốc?

`map` biến đổi từng phần tử, `filter` lọc, `reduce` gộp thành một giá trị; cả ba không đổi mảng gốc. Method mutating gồm `push`, `pop`, `splice`, `sort`, `reverse`, `fill`; bản không mutate là `toSorted`, `toReversed`, `toSpliced`, `with` (ES2023).

#array#functional#immutability
Junior

Optional chaining `?.` và nullish coalescing `??` khác gì `&&` và `||`?

`a?.b` trả undefined nếu `a` là null/undefined thay vì ném lỗi. `a ?? b` chỉ dùng `b` khi `a` là null/undefined, còn `a || b` dùng `b` với mọi giá trị falsy (0, "", false). Vì vậy `??` an toàn hơn để đặt giá trị mặc định.

#es2020#operators#null-safety
Junior

Vì sao 0.1 + 0.2 !== 0.3 trong JavaScript? Xử lý thế nào?

Number là số thực 64-bit IEEE 754 nhị phân, nên 0.1 và 0.2 không biểu diễn chính xác, tổng ra 0.30000000000000004. So sánh bằng sai số (epsilon), làm tròn khi hiển thị, hoặc tính tiền bằng số nguyên (đơn vị nhỏ nhất), BigInt hay thư viện decimal.

#number#floating-point#ieee754
Mid

`this` trong JavaScript được xác định như thế nào?

this được quyết định lúc gọi hàm (không phải lúc định nghĩa), trừ arrow function: nó lấy this của scope bao ngoài.

#this#function
Mid

call, apply, bind khác nhau thế nào? Tự viết bind

`call(ctx, a, b)` và `apply(ctx, [a, b])` gọi hàm ngay với `this` chỉ định (khác ở cách truyền đối số). `bind(ctx, ...pre)` trả về hàm mới đã khóa `this` và đối số đầu (partial application), không gọi ngay; `this` đã bind không thể bị override bởi call/apply.

#this#call#apply
Mid

debounce và throttle khác nhau thế nào? Viết code mỗi loại

Debounce hoãn gọi hàm cho đến khi ngừng kích hoạt đủ N ms (phù hợp ô tìm kiếm, resize xong). Throttle đảm bảo hàm chạy tối đa một lần mỗi N ms (phù hợp scroll, mousemove). Cả hai đều dựa vào closure giữ timer hoặc timestamp.

#debounce#throttle#performance
Mid

ES Modules khác CommonJS thế nào? Live binding và tree shaking là gì?

ESM (`import`/`export`) được phân tích tĩnh, bất đồng bộ, export là live binding (tham chiếu sống) và hỗ trợ tree shaking, top-level await. CommonJS (`require`) chạy đồng bộ lúc runtime, export là bản sao giá trị tại thời điểm gán trên `module.exports`.

#modules#esm#commonjs
Mid

Event bubbling, capturing và event delegation là gì?

Sự kiện DOM đi qua 3 pha: capturing (từ window xuống target), target, rồi bubbling (từ target lên). Event delegation gắn một listener ở phần tử cha và dựa vào `event.target` để xử lý con, giúp ít listener hơn và hoạt động với phần tử thêm động.

#dom#events#bubbling
Mid

Event loop hoạt động thế nào? Microtask vs macrotask?

JS đơn luồng; event loop chạy hết code đồng bộ, rồi xử lý toàn bộ microtask (Promise.then) trước, sau đó mới lấy 1 macrotask (setTimeout, I/O) tiếp theo.

#async#promise
Mid

Promise.all, allSettled, race, any khác nhau thế nào?

all: tất cả thành công, 1 lỗi là reject; allSettled: đợi hết, không bao giờ reject; race: kết quả đầu tiên (thành công hoặc lỗi); any: thành công đầu tiên.

#promise#async
Mid

Prototype và prototype chain là gì? class khác function constructor ra sao?

Mỗi object có liên kết nội bộ [[Prototype]] tới object khác; khi truy cập property không có sẵn, engine đi ngược chuỗi này đến null. `class` chỉ là cú pháp trên prototype, nhưng không hoisting như function, bắt buộc dùng `new` và chạy strict mode.

#prototype#class#inheritance
Mid

Shallow copy và deep copy khác nhau thế nào? structuredClone có giới hạn gì?

Shallow copy (spread, Object.assign, slice) chỉ copy cấp đầu, object lồng nhau vẫn chung tham chiếu. Deep copy sao chép đệ quy: dùng `structuredClone` (hỗ trợ Date, Map, Set, vòng tham chiếu; không clone được function, DOM, class instance giữ prototype).

#copy#reference#structuredClone
Senior

Garbage collection hoạt động thế nào? Các nguyên nhân memory leak phổ biến

JS dùng mark-and-sweep: object không còn reachable từ root (global, call stack) thì bị thu hồi; reference counting không xử lý được vòng tham chiếu. Leak xảy ra khi còn tham chiếu không cần: global, listener/timer chưa dọn, closure giữ object lớn, cache không giới hạn, DOM detached.

#memory#gc#memory-leak
Senior

Iterator protocol và generator hoạt động thế nào? Dùng khi nào?

Iterable có method `[Symbol.iterator]()` trả về iterator với `next()` cho `{ value, done }`. Generator (`function*`) tạo iterator có thể tạm dừng ở `yield` và nhận giá trị qua `next(x)`, cho phép lazy evaluation, chuỗi vô hạn và luồng điều khiển hai chiều.

#generator#iterator#symbol
Senior

Map, Set, WeakMap, WeakSet và WeakRef khác nhau thế nào?

`Map`/`Set` giữ thứ tự chèn, key là bất kỳ kiểu nào (so sánh SameValueZero). `WeakMap`/`WeakSet` chỉ nhận object làm key, giữ tham chiếu yếu nên không cản GC, không iterate được, không có `size`. `WeakRef` giữ tham chiếu yếu tới một object, `deref()` có thể trả undefined.

#map#set#weakmap
Senior

Microtask starvation là gì? Làm sao tránh chặn event loop?

Event loop chạy hết toàn bộ microtask queue (kể cả microtask mới sinh ra) trước khi sang macrotask hay render. Nếu microtask liên tục tự lên lịch microtask khác, timer, I/O và render bị bỏ đói (starvation) và trang đứng. Tránh bằng cách nhường quyền qua macrotask (`setTimeout`, `MessageChannel`, `scheduler.yield`).

#event-loop#microtask#performance
Senior

Proxy và Reflect là gì? Ứng dụng và hạn chế

`Proxy` bọc một object và chặn thao tác cơ bản (get, set, has, deleteProperty, ownKeys, apply...) qua các trap. `Reflect` cung cấp phiên bản mặc định của các thao tác đó, dùng trong trap để giữ đúng ngữ nghĩa. Ứng dụng: reactivity (Vue 3), validation, logging, default value.

#proxy#reflect#metaprogramming