30/09/2019, 08:25

JavaScript và những câu hỏi khó – Part 1

Dạo gần đây trên cộng đồng mạng đang nổi lên một repo rất hot javascript-questions, mỗi ngày nhận được tới hàng ngàn star. Tại thời điểm mình viết bài này là đã hơn 6000 ⭐️rồi. Mình cũng theo trend vào đọc thử và thấy có rất nhiều câu hỏi hay, nên cũng đã contribute một bản dịch ...

Dạo gần đây trên cộng đồng mạng đang nổi lên một repo rất hot javascript-questions, mỗi ngày nhận được tới hàng ngàn star. Tại thời điểm mình viết bài này là đã hơn 6000 ⭐️rồi.

Mình cũng theo trend vào đọc thử và thấy có rất nhiều câu hỏi hay, nên cũng đã contribute một bản dịch tiếng Việt, đồng thời chia sẻ tại đây với mọi người.

Hi vọng mọi người sẽ có thêm những trải nghiệm mới mẻ với JavaScript.

Trên đời vốn chỉ có 2 loại ngôn ngữ lập trình: loại bị nhiều người chê và loại không ai thèm dùng.

1. Ouput là gì?

  • A: Lydia và undefined
  • B: Lydia và ReferenceError
  • C: ReferenceError và 21
  • D: undefined và ReferenceError
Đáp án: D

Trong hàm chúng ta đã khai báo biến name với var. Điều đó có nghĩa là biến này sẽ được hoisted (một vùng nhớ sẽ được set up khi biến được khởi tạo) với giá trị mặc định là undefined, cho tới khi chúng ta thực sự định nghĩa biến đó. Trong hàm này, chúng ta chưa hề định nghĩa biến name tại dòng mà ta log ra, vậy nên giá trị mặc định của nó vẫn là undefined.

Các biến được khai báo với keyword let (và const) cũng được hoisted nhưng không giống như var, chúng không được khởi tạo. Chúng ta sẽ không thể truy cập chúng cho tới khi chúng ta khai báo (khởi tạo) chúng. Người ta gọi đó là “temporal dead zone”. Khi ta truy cập đến một giá trị trước khi chúng được khai báo, JavaScript sẽ throws một ReferenceError.

2. Output sẽ là gì?

  • A: 0 1 2 and 0 1 2
  • B: 0 1 2 and 3 3 3
  • C: 3 3 3 and 0 1 2
Đáp án: C

Bởi vì event queue trong JavaScript, hàm setTimeout callback sẽ được gọi sau khi vòng lặp được thực hiện. Bời vì biến i trong vòng lặp đầu tiên được khai báo với từ khóa var, nên nó sẽ là một biến global. Trong suốt vòng lặp, mỗi lần chúng ta tăng giá trị của i lên 1, sử dụng phép toán ++. Cho tới khi callback setTimeout được gọi, giá trị của i đã trở thành 3 rồi.

Trong vòng lặp thứ 2, biến i được khai báo với từ khóa let, có nghĩa nó là một biến block-scoped (block là những gì được viết bên trong cặp ngoặc { }). Tại mỗi vòng lặp, i sẽ là một biến mới có một giá trị mới, và giá trị đó có scope là bên trong vòng lặp mà thôi.

3. Output sẽ là gì?

  • A: 20 and 62.83185307179586
  • B: 20 and NaN
  • C: 20 and 63
  • D: NaN and 63
Đáp án: B

Chú ý rằng giá trị diameter là một hàm thông thường, còn perimeter là một arrow function.

Không giống như hàm thông thường, với arrow function, biếnthis sẽ trỏ tới surrounding scope! Có nghĩa là khi chúng ta gọi perimeter, nó sẽ không được gọi bởi shape object, mà nó được gọi bởi object nào đó tại surrounding scope (ví dụ window chẳng hạn).

Khi không có giá trị radius tại object đó, nó sẽ trả về undefined.

4. Ouput là gì?

  • A: 1 and false
  • B: false and NaN
  • C: false and false
Đáp án: A

Phép toán cộng + sẽ convert một toán hạng sang dạng number. true là 1, và false is 0.

Chuỗi 'Lydia' là một truthy value. Điều chúng ta thật sự đang hỏi chính là “có phải một giá trị truthy là falsy?”. Rõ ràng câu trả lời là false rồi.

5. Cái nào đúng?