JavaScript chưa bao giờ được định sẵn để trở thành như hiện tại. Vào năm 1995, Brendan Eich đã ngồi tại Netscape và nhào nặn ra một bản nguyên mẫu chỉ trong mười ngày. Mười ngày. Đó là khoảng thời gian vừa đủ để viết một bản đặc tả tử tế, chứ chưa nói đến việc thiết kế một ngôn ngữ lập trình nhằm vận hành hàng tỷ thiết bị. Kết quả là một ngôn ngữ với những điểm kỳ quặc mà các nhà phát triển vẫn còn vấp phải sau gần ba thập kỷ. Tuy nhiên, chính sự sáng tạo vội vã đó đã trở thành môi trường thực thi (runtime) được triển khai rộng rãi nhất trong lịch sử phần mềm. Nó thành công không phải vì sự tinh tế, mà vì nó được tích hợp sẵn trong trình duyệt vào đúng thời điểm mà web cần đến nó.
Ra đời trong vội vã
Cuộc chiến trình duyệt giữa những năm chín mươi không phải là một cuộc cạnh tranh thân thiện. Netscape cần một ngôn ngữ kịch bản (scripting language) nhẹ nhàng có thể chạy song song với Java trong trình duyệt Navigator của mình. Eich được giao nhiệm vụ xây dựng một thứ gì đó trông đủ giống Java để làm hài lòng các giám đốc điều hành, nhưng cũng đủ đơn giản để những người không phải lập trình viên có thể dán vào các trang web. Thời hạn là vô lý. Ông đã tạo ra Mocha, sau đó đổi tên thành LiveScript, và cuối cùng là JavaScript như một chiến lược marketing để tận dụng sự phổ biến của Java.
Sự ra đời vội vã đó đã để lại những "vết sẹo" vĩnh viễn. Ép kiểu (type coercion) vẫn làm khó những người mới khi toán tử cộng (+) nối chuỗi và số mà không có cảnh báo. typeof null trả về "object" do một lỗi trong bản triển khai ban đầu mà không ai dám sửa vì sợ làm hỏng toàn bộ web. Việc tự động chèn dấu chấm phẩy (Automatic semicolon insertion) gây ra những lỗi ngầm (silent failures). Các biến được khai báo với var bị rò rỉ phạm vi (scope) theo những cách khó lường. Đây không phải là những lỗi thiết kế trừu tượng. Chúng là những sự khó chịu hàng ngày có nguồn gốc trực tiếp từ một đợt chạy nước rút kéo dài hai tuần vào tháng 5 năm 1995.
Một nguồn gốc kỳ lạ
Nhìn kỹ vào JavaScript, bạn sẽ thấy ba dòng dõi riêng biệt được khâu lại với nhau. Cú pháp
Tốc độ đó đã tạo điều kiện cho bước chuyển mình tiếp theo. Ryan Dahl đã phát hành Node.js vào năm 2009, tách V8 ra khỏi trình duyệt và bao bọc nó trong một mô hình nhập-xuất (I/O) không chặn và hướng sự kiện. Các máy chủ web từng khởi tạo một luồng mới cho mỗi yêu cầu đến, điều này khiến chúng bị sụp đổ dưới tải lượng truy cập đồng thời lớn. Node.js xử lý hàng chục nghìn kết nối đồng thời trên một luồng duy nhất bằng cách sử dụng một vòng lặp sự kiện và các hàm gọi lại bất đồng bộ. JavaScript đã tràn ra khỏi phía client để tiến vào server, vào các công cụ build, và cuối cùng là vào mọi thứ khác.
Ngôn ngữ hiện diện khắp mọi nơi
Giờ đây, JavaScript chạy ở những nơi mà người tạo ra nó chưa từng tưởng tượng tới.
Ở phía frontend, React và Vue định hình cách các giao diện hiện đại được xây dựng. Các thành phần cập nhật để phản hồi lại các thay đổi trạng thái mà không cần trình duyệt phải thực hiện việc tải lại toàn bộ trang một cách tốn kém. Ở phía backend, Node.js cung cấp sức mạnh cho các API và dịch vụ thời gian thực, trong khi các môi trường thực thi mới hơn như Bun đang thử nghiệm với việc quản lý gói nhanh hơn và tích hợp sẵn khả năng đóng gói.
React Native chuyển đổi mã JavaScript thành các view nền tảng gốc, cho phép các đội ngũ phát hành các ứng dụng di động cho iOS và Android mà không cần phải duy trì hai cơ sở mã hoàn toàn riêng biệt bằng Swift và Kotlin. Electron bao bọc các công nghệ web bên trong một lớp vỏ Chromium để xây dựng phần mềm máy tính, đó cũng là cách mà cả Slack và Visual Studio Code hiện diện trên laptop của bạn. Ngôn ngữ này thậm chí còn nằm trong các cloud functions và các trình xử lý edge computing, thực thi logic chỉ cách người dùng cuối vài mili giây thông qua các mạng lưới phân tán.
Nghịch lý của sự dư thừa
Sự phổ biến luôn đi kèm với cái giá của nó. Hệ sinh thái này vô cùng khổng lồ, và quy mô đó tạo ra sự lo âu. Một công cụ build mới xuất hiện trước khi bạn kịp hoàn tất việc cấu hình công cụ trước đó. Các framework trỗi dậy và suy tàn về mức độ phổ biến theo những mốc thời gian cảm giác như các mùa trong năm. Bạn có thể giải quyết hầu hết mọi vấn đề mà không cần rời khỏi thế giới JavaScript, nhưng trước tiên bạn phải lựa chọn giữa hàng tá các giải pháp mang tính áp đặt cao. Các cây phụ thuộc trở nên sâu và dễ gãy. Một gói dùng để thêm khoảng trắng vào bên trái mảng có thể làm hỏng hàng nghìn dự án hạ nguồn khi nó biến mất khỏi registry.
Không có điều nào trong số này là ngẫu nhiên. JavaScript lộn xộn vì web cũng lộn xộn. Nó là một "chiếc bánh nhiều lớp" hữu cơ được tạo nên từ tính tương thích ngược, các tiêu chuẩn được vội vã ban hành và các lợi ích thực thi cạnh tranh nhau. Tuy nhiên, chính sự lộn xộn đó lại là lý do khiến ngôn ngữ này trở nên mạnh mẽ. Web có mặt ở khắp mọi nơi, và vì JavaScript mặc định tồn tại trong mọi trình duyệt, nó là thứ gần nhất với một môi trường thực thi vạn năng mà chúng ta có.
Nó đã ngừng việc chỉ là một ngôn ngữ kịch bản từ lâu. JavaScript giờ đây là một nền tảng phần mềm toàn cầu, được xây dựng trong mười ngày, được gắn kết bởi một khế ước vô hình rằng web không được làm hỏng những gì đã có trước đó. Hãy tìm hiểu những vết sẹo của nó cùng với những thế mạnh, và bạn đang học về chính lịch sử của internet hiện đại.
