Bạn có bao giờ gặp phải một số câu hỏi kỹ thuật khó chịu trong một cuộc phỏng vấn về JavaScipt và cảm giác rằng mình biết câu hỏi này nhưng chịu không thể giải thích được. Bài viết này tóm tắt 20 khái niệm bạn nên biết để có thể vượt qua các cuộc phỏng vấn và không phải hối tiếc vì mình đã không có sự chuẩn bị kỹ càng.
Lưu ý: trong bài viết có một số link đến Medium và bạn có thể gặp khó khăn khi đọc từ IP Việt Nam. Bạn cần sử dụng VPN để truy cập. Một số bài cần có tài khoản Medium để đọc
1/Sự khác nhau giữa Arrow và Regular function
- Giá trị this (theo ngữ cảnh): trong một
regular
function, giá trịthis
không liên quan gì đến class mà nó được định nghĩa; thay vào đó, nó phụ thuộc vào đối tượng mà nó được gọi đến; bên trong mộtarrow
function giá trị này luôn bằng giá trị này từ hàm bên ngoài - Constructors: các
regular
function có thể dễ dàng tạo các đối tượng, trong khi mộtarrow
function không thể được sử dụng như một constructor - Arguments object: là một đối tượng dạng mảng đặc biệt chứa danh sách các đối số (arguments) mà hàm đã được gọi, bên trong một
arrow
function, arguments object được giải quyết một cách từ vựng: nó truy cập các đối số từ hàm bên ngoài - Implicit return: các hàm
regular
sử dụng câu lệnh biểu thức trả về (expression statement) – nếu không, nó sẽ chỉ trả về không xác định, trong khi với các hàmarrow
, nếu chúng chứa một biểu thức (expression) và thiếu dấu ngoặc nhọn của hàm, thì biểu thức được trả về ngầm định (Implicit return).
Để hiểu hơn về sư khác nhau giữa các hàm arrow và regular function bạn có thể xem thêm
2/Từ khóa This hoạt động thế nào?
- Từ khóa
this
đề cập đến một đối tượng, đối tượng đó đang thực thi đoạn mã javascript hiện tại - Mỗi hàm javascript trong khi thực thi đều có tham chiếu đến ngữ cảnh thực thi hiện tại của nó, được gọi là this – ngữ cảnh thực thi có nghĩa là ở đây là cách hàm được gọi
- Để hiểu từ khóa this, chúng ta chỉ cần biết hàm được gọi như thế nào, khi nào và từ đâu, không quan trọng hàm được khai báo hoặc định nghĩa như thế nào và ở đâu.
Đọc thêm và xem các ví dụ về từ khóa this trong JavaScript
3/Callbacks và closures là gì?
- Callback: một hàm có thể truy cập được bởi một hàm khác và được gọi sau hàm đầu tiên – nếu hàm đầu tiên đó hoàn thành
- Closure: được tạo bất cứ khi nào một biến được xác định bên ngoài phạm vi hiện tại được truy cập từ trong một số phạm vi bên trong – nó cho phép bạn truy cập vào phạm vi của chức năng bên ngoài từ một chức năng bên trong
- Để sử dụng
Closure
chỉ cần xác định một hàm bên trong một hàm khác và hiển thị nó
Xem thêm về Callbacks và Closures trong JavaScript:
4/Anonymous Function là gì?
- Anonymous Function là một hàm được khai báo mà không có bất kỳ hàm nào có tên định danh để tham chiếu đến nó – nó thường không thể truy cập được sau khi tạo. Các chức năng này được tạo tại thời điểm chạy
Đọc thêm về Anonymous Function:
5/ Higher-Order Functions?
- Các hàm Higher-Order là các hàm nhận một hàm dưới dạng đối số hoặc trả về một hàm.
- Ví dụ: Array.prototype.map, Array.prototype.filter và Array.prototype.reduce là một số hàm bậc cao được tích hợp trong ngôn ngữ này.
Xem thêm về high-order function:
6/“strict” mode trong JavaScript là gì?
- Strict mode cho phép kiểm tra lỗi nghiêm ngặt hơn trong code và giúp gỡ lỗi dễ dàng hơn
- Bạn bật chế độ nghiêm ngặt bằng cách thêm “use strict”; ở đầu tập tin
Đọc thêm về Strict mode trong JavaScript:
7/ Khác nhau giữa Promises và Async/Await
- Phạm vi (scope): trong một
promise
, chỉ promise chain là không đồng bộ, không chặn việc thực thi. Vớiasync / await
, toàn bộ hàmwrapper
là không đồng bộ - Logic: trong một
promise
, công việc đồng bộ có thể được xử lý trong cùng một lệnh gọi lại và nhiều promises có thể được xử lý bằngPromise.all.
Với async / await, công việc đồng bộ cần được đặt bên ngoài callback và nhiều promises có thể được xử lý bằng các biến đơn giản hơn
Xử lý lỗi: Promises: then, catch, finally
; Async / await: try, catch, finally
Xem thêm về Promises và Async/Await trong JavaScript:
8/ Khác nhau giữa Mutable và Immutable trong JS
- Sự khác biệt giữa immutable (bất biến) và mutable (có thể thay đổi): nếu một mục có thể thay đổi, khi thay đổi giá trị của biến tham chiếu, nó cũng sẽ ảnh hưởng đến giá trị của biến được tham chiếu ban đầu
- Các kiểu dữ liệu ban đầu như số, chuỗi và Boolean là immutable – không thể thay đổi giá trị của các loại đó bằng cách thay đổi tham chiếu – bạn có thể kết hợp chúng và lấy các giá trị mới từ chúng, nhưng khi bạn chỉ định một giá trị cụ thể, giá trị đó sẽ luôn luôn giữ nguyên; bạn có thể đặt một tên biến trỏ tới một giá trị mới, nhưng giá trị trước đó vẫn được giữ trong bộ nhớ
- Mutable là một loại biến có thể được thay đổi bằng tham chiếu của nó – trong JS chỉ có các đối tượng và mảng là có thể thay đổi: bạn có thể thay đổi các thuộc tính của chúng; ví dụ: khiến một giá trị đối tượng duy nhất có nội dung khác nhau tại các thời điểm khác nhau
Xem thêm và xem các ví dụ về immutable và mutable trong JavaScript:
9/Typed language là gì?
- Trong các type languages, các giá trị được liên kết với các giá trị chứ không phải với các biến. Type language có thể là tĩnh (static) hoặc động (dynamic)
- Static: biến chỉ có thể chứa một kiểu, giống như trong Java: một biến được khai báo là chuỗi chỉ có thể nhận một tập hợp các ký tự và không có gì khác
- Dynamic: biến có thể chứa nhiều kiểu – như trong JS: một biến có thể nhận số, ký tự, v.v.
Xem thêm về static và dynamic language:
10/ Hoisting là gì?
- Hành vi mặc định của JavaScript là di chuyển tất cả các khai báo lên đầu phạm vi hiện tại (lên đầu các scripts hoặc hàm hiện tại)
- JavaScript chỉ dời các khai báo ( declarations), không lưu trữ các khởi tạo (initializations)
Xem thêm về Hoisting trong JavaScript:
11/ Event delegation là gì trong JavaScript?
- Một kỹ thuật đơn giản mà bạn thêm một trình xử lý sự kiện duy nhất vào phần tử mẹ để tránh phải thêm trình xử lý sự kiện vào nhiều phần tử con
- Sử dụng event delegation (ủy quyền sự kiện), bạn có thể thêm event handler (trình xử lý sự kiện) vào một phần tử, đợi sự kiện xuất hiện từ phần tử con và dễ dàng xác định sự kiện bắt nguồn từ phần tử nào
Tìm hiểu thêm về event delegation trong JavaScript:
12/ Sự khác nhau giữa call, apply & bind?
- Bằng cách sử dụng
call
,apply
vàbind
, bạn có thể xác định rõ ràngthis
nên tham khảo đến đâu bind
có thể đặc biệt hữu ích khi bạn muốn sử dụng các sự kiện để truy cập các thuộc tính của một lớp trong một lớp khác- Sự khác biệt chính là
apply
thực thi hàm ngay lập tức, trong khibind
trả về một hàm call
vàapply
rất giống nhau – chúng gọi một hàm với ngữ cảnh cụ thể này và các đối số tùy chọn- Sự khác biệt là
call
yêu cầu các đối số được truyền từng cái một vàapply
nhận các đối số dưới dạng một mảng
Đọc thêm và xem các ví dụ về call
, apply
và bind
:
13/Sự khác nhau giữa host và native objects?
- Các objects có thể được chia thành hai loại chính, tùy thuộc vào môi trường và ngôn ngữ
- Host objects: môi trường cụ thể – ví dụ: Trình duyệt cung cấp các đối tượng như cửa sổ, node cho NodeList, v.v.
- Native / Built-in objects: đối tượng tiêu chuẩn do JS cung cấp – đôi khi được gọi là đối tượng toàn cục; JS chủ yếu được xây dựng bởi các đối tượng gốc được phân loại này (Chuỗi, Số, v.v.)
Xem thêm về host objects và native objects:
14/ Curry function là gì trong JavaScript?
- Currying là một quá trình trong lập trình hàm, trong đó chúng ta có thể chuyển đổi một hàm có nhiều đối số thành một chuỗi các hàm lồng nhau – nó trả về một hàm mới mong đợi đối số tiếp theo nội tuyến (inline).
- Carrying chuyển đổi hàm từ một hàm từ có thể gọi được (callable) f (a, b, c) thành f (a) (b) (c)
- Nó cho phép chúng ta dễ dàng nhận các phần tử, tránh chuyển cùng một biến nhiều lần
- Nó tạo ra các hàm lồng nhau (nesting) theo số lượng các đối số của hàm để mỗi hàm nhận một đối số: nếu không có đối số thì không có currying.
Đọc thêm về curry function trong JavaScript:
15/Event loop là gì?
- Trong hầu hết các trình duyệt, có một vòng lặp sự kiện (event loop) cho mỗi tab trình duyệt, để làm cho mọi quy trình được tách biệt và tránh một trang web có vòng lặp vô hạn hoặc xử lý nặng để chặn toàn bộ trình duyệt của bạn
- Môi trường quản lý nhiều vòng lặp sự kiện đồng thời, để xử lý các lệnh gọi API
- Các Web Workers cũng chạy trong vòng lặp sự kiện của riêng chúng.
- Bạn chủ yếu cần phải chú ý rằng code của mình sẽ chạy trên một vòng lặp sự kiện duy nhất.
- Bất kỳ mã JavaScript nào mất quá nhiều thời gian để trả lại quyền kiểm soát cho vòng lặp sự kiện sẽ chặn việc thực thi bất kỳ mã JavaScript nào trong trang, thậm chí chặn chuỗi giao diện người dùng và người dùng không thể nhấp vào, cuộn trang, v.v.
Tìm hiểu thên về Event loop:
16/Event propagation là gì?
- Event propagation là một cơ chế xác định cách sự kiện lan truyền hoặc di chuyển qua cây DOM để đến mục tiêu của nó và sau đó
- Trong trình duyệt hiện đại, việc truyền bá sự kiện diễn ra theo hai giai đoạn: giai đoạn capturing và giai đoạn bubbling
- Capturing: các sự kiện truyền từ cửa sổ xuống qua cây DOM đến nút đích – chỉ hoạt động với các trình xử lý sự kiện được đăng ký với phương thức
addEventListener ()
khi đối số thứ ba được đặt thành true - Bubbling: Trong giai đoạn này, sự kiện lan truyền hoặc tạo bong bóng (bubble) sao lưu cây DOM, từ phần tử đích lên đến cửa sổ, lần lượt truy cập tất cả tổ tiên của phần tử đích – được hỗ trợ trong tất cả các trình duyệt và nó hoạt động với tất cả các trình xử lý, bất kể về cách chúng được đăng ký, ví dụ: sử dụng
onclick
hoặcaddEventListener ()
Tìm hiểu thêm về Event propagation trong JavaScript:
17/Sự khác nhau giữa Cookies, Local Storage và Session Storage là gì?
- Browser storage: dữ liệu không bao giờ được chuyển đến máy chủ & chỉ có thể được đọc ở phía client; giới hạn lưu trữ khoảng 5MB
- Session vs local storage: session chỉ là tạm thời – dữ liệu được lưu trữ cho đến khi đóng tab / trình duyệt; local không có ngày hết hạn
- Nhược điểm khi lưu trữ: không an toàn, giới hạn ở các chuỗi, nguy hiểm cho XSS
- Cookie: lưu trữ dữ liệu có ngày hết hạn, giới hạn lưu trữ khoảng 4KB, được gửi đến máy chủ cho mỗi yêu cầu, đọc / ghi trên cả phía máy khách và máy chủ (nếu HttpOnly thì không thể truy cập vào các tập lệnh phía máy khách)
Tìm hiểu thêm về Cookies, Local Storage, Session Storage trong JavaScript:
18/Content Security Policy (CSP) là gì?
- Content Security Policy (CPS): Chính sách bảo mật nội dung là một HTTP header cho phép người điều hành trang web kiểm soát chi tiết đối với nguồn tài nguyên trên trang web của họ có thể được tải từ đâu.
- Việc sử dụng header này là phương pháp tốt nhất để ngăn chặn các lỗ hổng cross-site scripting (XSS).
- Do khó khăn trong việc trang bị thêm (retrofitting) CSP vào các trang web hiện có, CSP là bắt buộc đối với tất cả các trang web mới và được khuyến nghị thực hiện cho tất cả các trang web có nguy cơ cao.
Tìm hiểu thêm về Content Security Policy (CSP) trong JavaScript:
19/Cross-Site Scripting (XSS) là gì?
- Cross-Site Scripting (XSS) là một cuộc tấn công xảy ra khi kẻ tấn công sử dụng một ứng dụng web để gửi mã độc hại, thường ở dạng một tập lệnh phía trình duyệt, đến một người dùng cuối khác
- Trang do server cung cấp khi có yêu cầu không bị thay đổi; thay vào đó, một cuộc tấn công XSS khai thác một điểm yếu trong một trang bao gồm một biến được gửi trong một yêu cầu hiển thị ở dạng thô trong phản hồi
Tìm hiểu thêm về các cuộc tấn công Cross-Site Scripting (XSS):
20/CORS (Cross-Origin Resource Sharing) là gì?
- Cross-Origin Resource Sharing (CORS), Chia sẻ tài nguyên xuyên nguồn, là một cơ chế sử dụng HTTP header bổ sung để yêu cầu trình duyệt cung cấp cho ứng dụng web chạy tại một nguồn, quyền truy cập vào các tài nguyên được chọn từ một nguồn khác
- Một ứng dụng web thực thi một yêu cầu HTTP có nguồn gốc chéo (cross-origin) khi nó yêu cầu một tài nguyên có nguồn gốc khác (miền, giao thức hoặc cổng) từ chính nó
Xem thêm về Cross-Origin Resource Sharing:
Kết
Bài viết được dựa trên bài viết gốc The JavaScript Cheatsheet you need in 2021 đăng trên Medium. Hy JavaSript cheatsheet này sẽ giúp bạn chuẩn bị tốt hơn cho buổi phỏng vấn về JavaScript của mình.
Bạn cũng có thể xem thêm 11 Khái niệm JavaScript cơ bản mọi nhà phát triển nên biết trong một bài viết trước trên ITguru blog.