Họ đang đo gì
Bạn có mô hình về cách JavaScript tra cứu thuộc tính, hay chỉ dùng class như trong Java.
Trả lời ngắn~30 giây
Mỗi object có một liên kết nội bộ tới object khác gọi là prototype. Khi bạn đọc một thuộc tính không có trên object, engine đi ngược lên chuỗi đó cho tới khi tìm thấy hoặc chạm null. class không thêm mô hình mới nào — nó tạo hàm khởi tạo và gắn phương thức lên Constructor.prototype, chỉ là cú pháp dễ đọc hơn và có vài ràng buộc chặt hơn.
Giải thích sâu
Điều đáng nói là chuỗi này dùng cho ĐỌC chứ không cho GHI. Gán obj.x = 1 luôn tạo thuộc tính ngay trên obj, che đi thuộc tính cùng tên ở prototype thay vì sửa nó. Đây là nguồn nhầm lẫn kinh điển: sửa một object con tưởng ảnh hưởng tới cha, thực ra chỉ tạo bản che. Ngoại lệ là khi prototype định nghĩa setter — lúc đó setter được gọi.
Hệ quả thực tế quan trọng nhất là vì sao không nên sửa prototype có sẵn. Thêm Array.prototype.last nghĩa là mọi mảng trong toàn bộ tiến trình — kể cả trong thư viện bên thứ ba — bỗng có thuộc tính đó, và for…in sẽ liệt kê nó. Nếu một thư viện khác cũng định nghĩa last với ngữ nghĩa khác thì một trong hai hỏng, và lỗi hiện ra ở nơi hoàn toàn không liên quan.
Khác biệt thật giữa class và hàm khởi tạo kiểu cũ: thân class luôn ở strict mode, phương thức không liệt kê được trong for…in, gọi class mà thiếu new là lỗi ngay, và extends xử lý đúng cả việc kế thừa từ built-in như Array — điều mà cách viết cũ làm rất chật vật. Nên class không chỉ là đường cú pháp thuần tuý, nó còn siết vài chỗ dễ sai.
Câu hỏi tiếp theo họ sẽ hỏi
?__proto__ và prototype khác nhau chỗ nào?
prototype là thuộc tính trên HÀM, dùng làm prototype cho các object tạo bằng new hàm đó. __proto__ (chuẩn hoá thành Object.getPrototypeOf) là liên kết thật của một object tới prototype của nó. Nhầm hai cái này là hiểu nhầm phổ biến nhất về chủ đề này.
?Object.create(null) để làm gì?
Tạo object không có prototype, nên không có toString, hasOwnProperty, và quan trọng nhất là không có __proto__. Dùng làm từ điển an toàn với khoá từ người dùng — đây chính là cách chặn prototype pollution.
Trả lời thế này là mất điểm
- Nói
classcủa JavaScript giống hệt Java. Không có kiểu tĩnh, không có overload, không có private thật trước#, và kế thừa vẫn là prototype.