Mở đầu
Tập tài liệu khảo sát này được biên soạn với sứ mệnh trang bị cho bạn một phác đồ tổng quan về những khái niệm cốt lõi cần phải nắm bắt vững vàng trong quá trình chập chững làm quen với hệ sinh thái JavaScript. Mục tiêu tối thượng của chúng tôi là tiến hành trám đầy những lỗ hổng kiến thức – những cạm bẫy vô hình mà các nhà phát triển mới vào nghề thường xuyên vấp phải và chịu những thất bại cay đắng trong những lần đầu tiên tương tác với ngôn ngữ này. Thông qua việc hé lộ những chi tiết kiến trúc tinh vi đan xen xuyên suốt các chương, hy vọng rằng ngọn lửa tò mò học thuật bên trong bạn đã được thắp sáng, thôi thúc bạn khao khát được đào sâu hơn nữa vào tận cùng gốc rễ của ngôn ngữ. Khối lượng kiến thức khổng lồ còn lại, phức tạp và đa chiều hơn gấp bội phần so với những gì chúng ta có thể cô đọng trong vài chương ngắn ngủi này, sẽ được từ từ bóc tách và phơi bày một cách toàn diện trong các tập tiếp theo của bộ sách. Lời khuyên vàng ngọc nhất vẫn là: hãy luôn giữ một nhịp độ học tập chậm rãi và từ tốn. Thay vì lao như thiêu thân sang tập sách tiếp theo chỉ để thỏa mãn cảm giác hoàn thành ảo tưởng, hãy dành quỹ thời gian quý báu để quay lại, nghiền ngẫm, đối chiếu những kiến thức đã học với chính những dòng mã nguồn mà bạn đang nhào nặn trong các dự án thực tế hiện tại. Khi tâm trí bạn thực sự sẵn sàng, chương tổng kết này sẽ phác thảo ra một tấm bản đồ tư duy chiến lược, phân chia toàn bộ ngôn ngữ thành ba trụ cột chống đỡ vĩ đại, đồng thời cung cấp một định hướng rõ ràng về lộ trình chinh phục hệ thống kiến thức đồ sộ đang chờ đón bạn ở phía trước.
Trụ cột đầu tiên: Phạm vi và Bao đóng
Kiến trúc tổ chức các biến số vào trong những đơn vị chứa đựng mang tính phân cấp (chẳng hạn như các hàm điện toán hay các khối mã lệnh) cấu thành nên một trong những đặc tính nền tảng và mang tính sống còn nhất của bất kỳ một ngôn ngữ lập trình nào; có thể khẳng định mạnh mẽ rằng, hoàn toàn không có một đặc tính kiến trúc nào khác lại sở hữu một sức mạnh chi phối lớn lao đến hành vi vận hành tổng thể của các hệ thống chương trình như vậy.
Cơ chế phạm vi từ vựng
Hãy hình dung một cách trực quan, các phạm vi hoạt động giống như những chiếc xô chứa nước đa kích cỡ, và các biến số chính là những viên bi ve đầy màu sắc mà bạn muốn thả vào bên trong những chiếc xô đó. Mô hình phạm vi (scope model) của một ngôn ngữ đóng vai trò là một bộ luật tối cao, cung cấp cho hệ thống các quy tắc nghiêm ngặt để xác định chính xác xem viên bi màu nào sẽ được phép rơi vào chiếc xô có màu sắc tương ứng nào. Các phạm vi sở hữu khả năng lồng ghép (nest) sâu vào bên trong nhau tạo thành một hệ thống phân cấp phức tạp, và đối với bất kỳ một biểu thức hay một câu lệnh riêng lẻ nào đang được thực thi, nó chỉ được cấp quyền truy cập và thao tác với những biến số đang tồn tại ở ngay tại cấp độ lồng ghép hiện tại của nó, hoặc những biến số nằm ở các tầng phạm vi cao hơn/bao bọc bên ngoài nó; ngược lại, mọi biến số bị giam giữ ở các tầng phạm vi thấp hơn/nằm sâu bên trong đều bị che giấu hoàn toàn và vĩnh viễn không thể truy cập từ bên ngoài.
Cơ chế phân cấp và che giấu thông tin này chính là cách thức vận hành tiêu chuẩn của khái niệm phạm vi trên phần lớn các ngôn ngữ điện toán đương đại, một triết lý thiết kế được giới hàn lâm định danh là Lexical scope (Tạm dịch: Phạm vi từ vựng.). Ranh giới của các đơn vị phạm vi này, cùng với phương thức mà các biến số bị giam giữ bên trong chúng, được hệ thống chốt hạ và đóng băng ngay tại thời điểm toàn bộ chương trình đang được quét qua và phân tích cú pháp tĩnh (tức là ở giai đoạn biên dịch). Nói một cách dễ hiểu hơn, đây là một quyết định mang tính chiến lược của kiến trúc sư phần mềm ngay tại thời điểm chắp bút viết mã (author-time): vị trí vật lý mà bạn quyết định đặt một hàm hoặc khai báo một khối mã lệnh sẽ đóng vai trò quyết định, nhào nặn nên toàn bộ cấu trúc phân cấp phạm vi vĩnh viễn của phân vùng chương trình đó. Ngôn ngữ JavaScript hoàn toàn và tuyệt đối tuân thủ triết lý phạm vi từ vựng, mặc cho vô số những luận điệu chỉ trích phủ nhận điều này, nguyên nhân của những lầm tưởng đó bắt nguồn từ hai đặc tính thiết kế độc lạ của mô hình này vốn không hề xuất hiện trên các ngôn ngữ phạm vi từ vựng truyền thống khác.
Những đặc tính độc nhất và hiện tượng bao đóng
Đặc tính kiến trúc kỳ lạ thứ nhất thường được cộng đồng biết đến với thuật ngữ Kéo lên (hoisting): đây là một hiện tượng quang học của trình biên dịch, nơi mà tất cả các biến số, bất chấp việc chúng được khai báo ở đâu trong một phạm vi, đều được hệ thống ảo thuật gia đối xử và ưu tiên xử lý như thể chúng đã được khai báo trân trọng ngay tại dòng đầu tiên trên cùng của phạm vi đó. Đặc tính kỳ lạ thứ hai nằm ở chỗ: những biến số được sinh ra bởi từ khóa var lại bị ép buộc phải tuân theo vòng đời của phạm vi hàm, hoàn toàn phớt lờ và xuyên thủng mọi ranh giới của các phạm vi khối nếu chúng vô tình được đặt bên trong đó. Tuy nhiên, cần phải khẳng định rõ ràng rằng: cả đặc tính Kéo lên lẫn hành vi phạm vi hàm của var đều hoàn toàn không đủ tư cách và sức nặng để chứng minh cho luận điểm lố bịch rằng JavaScript không phải là ngôn ngữ phạm vi từ vựng. Hơn thế nữa, các từ khóa khai báo thế hệ mới như let/const lại mang trong mình một hành vi báo lỗi vô cùng lập dị được đặt tên là Vùng chết tạm thời (TDZ), một hiện tượng tạo ra những biến số có thể nhìn thấy được bằng mắt thường nhưng lại bị hệ thống cấm vận, không cho phép sử dụng. Mặc dù trải nghiệm va chạm với TDZ có thể mang lại cảm giác vô cùng quái gở, nhưng đây cũng tuyệt đối không phải là một minh chứng phủ nhận sự tồn tại của cơ chế phạm vi từ vựng. Tất cả những hiện tượng này đơn thuần chỉ là những mảng màu sắc độc đáo, những đặc điểm thiết kế mang tính dị biệt của ngôn ngữ mà mọi kỹ sư phần mềm chuyên nghiệp bắt buộc phải dành thời gian nghiên cứu và làm chủ.
Hệ quả tất yếu, mang tính tự nhiên nhất sinh ra từ cơ chế phạm vi từ vựng khi nó được đặt trong một hệ sinh thái ngôn ngữ tôn vinh các hàm điện toán lên vị thế của những công dân hạng nhất (first-class values) như JavaScript, chính là sự xuất hiện của hiện tượng bao đóng. Khi một hàm nội bộ vươn tay ra tạo liên kết tham chiếu đến các biến số nằm ở không gian phạm vi bên ngoài nó, và sau đó bản thân cái hàm nội bộ đó lại được hệ thống vận chuyển, truyền tay đi như một gói dữ liệu thông thường để rồi bị gọi chạy tại những không gian phạm vi hoàn toàn xa lạ, nó vẫn kiên cường bám trụ và duy trì quyền truy cập trực tiếp vào các biến số thuộc về phạm vi nguyên thủy ban đầu của nó; hiện tượng bảo tồn bộ nhớ kỳ diệu này chính là định nghĩa của bao đóng. Trên khắp mọi mặt trận của ngành công nghiệp lập trình, nhưng đặc biệt mang tính quyết định trong hệ sinh thái này, cơ chế bao đóng chính là động cơ cốt lõi cung cấp năng lượng cho vô số các khuôn mẫu lập trình quan trọng bậc nhất, trong đó nổi bật nhất là mẫu thiết kế hệ thống khối (modules). Theo góc nhìn chuyên môn, các hệ thống khối chính là minh chứng hoàn hảo nhất cho việc tuân thủ một cách thuận chiều tự nhiên nhất (with the grain) đối với những nguyên lý tổ chức mã nguồn tinh hoa nhất của ngôn ngữ. Để có thể khai quật và thấu hiểu tận cùng về các khái niệm phạm vi, bao đóng và sự vận hành tinh vi của các hệ thống khối, việc nghiền ngẫm Tập 2 mang tên Scope & Closures là một nhiệm vụ bắt buộc.
Trụ cột thứ hai: Hệ thống Nguyên mẫu
Trụ cột chống đỡ thứ hai tạo nên sức mạnh vô song của ngôn ngữ chính là hệ thống kiến trúc các nguyên mẫu. Dù chương ba đã tiến hành một cuộc phẫu thuật khá sâu sắc về chủ đề này, nhưng tầm vóc hệ trọng của nó đòi hỏi chúng ta phải nhấn mạnh thêm một vài quan điểm kiến trúc mang tính định hình.
JavaScript tự hào vươn lên như một trong những ngôn ngữ điện toán hiếm hoi trên thế giới trao cho kỹ sư đặc quyền tối thượng: khả năng kiến tạo ra các thực thể đối tượng một cách trực tiếp, tường minh và tự do hoàn toàn, mà không hề bị ép buộc phải phác thảo trước cấu trúc thiết kế của chúng thông qua các khuôn mẫu lớp cứng nhắc. Trong suốt một thời kỳ dài đằng đẵng của lịch sử phát triển, cộng đồng đã miệt mài thiết kế và cố gắng nhào nặn mô hình lớp đè lên trên nền tảng của hệ thống nguyên mẫu – một nỗ lực tạo ra ảo giác kiến trúc được gọi là kế thừa nguyên mẫu – và hệ quả là với sự xuất hiện của từ khóa class trong phiên bản ES6, ngôn ngữ này dường như đã chính thức đặt cược nhân đôi, nghiêng hẳn cán cân về phía trường phái lập trình hướng đối tượng dựa trên các lớp truyền thống.
Thế nhưng, sự chuyển dịch trọng tâm đó lại vô tình ném một tấm màn nhung đen tối, che khuất đi vẻ đẹp toàn mỹ và thứ sức mạnh thuần khiết nhất của hệ thống nguyên mẫu: đó chính là năng lực siêu việt cho phép hai thực thể đối tượng hoàn toàn biệt lập có thể dễ dàng kết nối, móc nối với nhau và tiến hành hợp tác động (trong suốt thời gian các hàm/phương thức đang được thực thi) thông qua cơ chế chia sẻ chung một ngữ cảnh this. Mô hình kiến trúc Lớp thực chất chỉ là một khuôn mẫu thiết kế, một lớp vỏ bọc mà bạn có thể đắp lên trên thứ sức mạnh nền tảng đó. Tuy nhiên, một phương pháp tiếp cận hoàn toàn khác biệt, rẽ theo một hướng đi tư duy mang tính lật đổ, đó là hãy đơn giản là dang tay ôm trọn lấy bản chất của các đối tượng, hãy đối xử với đối tượng đúng như vị thế của một đối tượng, hãy ném mọi khái niệm về các lớp vào dĩ vãng, và cho phép các đối tượng đó tự do hợp tác với nhau thông qua sự ủy quyền của chuỗi nguyên mẫu. Triết lý thiết kế táo bạo này được vinh danh là sự Ủy quyền hành vi (behavior delegation). Khi xét trên khía cạnh tìm kiếm một phương tiện để tổ chức các khối dữ liệu và hành vi bên trong một hệ thống phần mềm, cơ chế ủy quyền này phô diễn một sức mạnh vượt trội và linh hoạt hơn gấp ngàn lần so với cơ chế kế thừa lớp truyền thống.
Thật trớ trêu thay, cơ chế kế thừa lớp lại luôn là thỏi nam châm thu hút gần như trọn vẹn mọi sự chú ý và nguồn lực nghiên cứu từ cộng đồng. Phần tài nguyên ít ỏi còn sót lại thì lại bị trường phái lập trình chức năng (FP) giành giật, với tư cách là một phong cách thiết kế mang tính chống lại lớp cực đoan. Sự phân cực này mang lại một nỗi buồn sâu sắc, bởi vì nó tàn nhẫn bóp nghẹt và dập tắt mọi cơ hội để cộng đồng tiến hành thăm dò, nghiên cứu cơ chế ủy quyền như một phương án thay thế tối ưu và hoàn toàn khả thi. Lời kêu gọi thiết tha nhất là bạn hãy đầu tư một khoảng thời gian đáng kể để đắm chìm vào Tập 3, Objects & Classes, để tận mắt chứng kiến cơ chế ủy quyền đối tượng thực sự chứa đựng một kho tàng tiềm năng khổng lồ vượt xa những gì chúng ta vẫn thường huyễn hoặc. Thông điệp cốt lõi ở đây hoàn toàn không phải là một sự bài xích mù quáng đối với từ khóa class, mà đó là một lời cảnh tỉnh đầy tính toán: các lớp không phải là con đường độc đạo duy nhất để nhào nặn và sử dụng các đối tượng, một thông điệp mà mọi kiến trúc sư hệ thống cần phải nghiêm túc khắc cốt ghi tâm. Có thể khẳng định một cách đầy tự hào rằng, cơ chế ủy quyền đối tượng chính là sự tuân thủ thuận chiều tự nhiên nhất (with the grain) đối với linh hồn của JavaScript, vượt xa khỏi những gì mà các khuôn mẫu lớp cứng nhắc có thể mang lại.
Trụ cột thứ ba: Kiểu dữ liệu và Sự ép kiểu
Trụ cột kiến trúc cuối cùng, và cũng là mảng tối thường xuyên bị bỏ rơi, hắt hủi và hiểu lầm tồi tệ nhất trong toàn bộ bản chất của JavaScript, chính là hệ thống quản lý kiểu dữ liệu và cơ chế chuyển đổi.
Một thực trạng vô cùng nhức nhối là đại bộ phận các nhà phát triển đang mang trong đầu những định kiến sai lệch và méo mó một cách trầm trọng về cách thức mà các hệ thống kiểu dữ liệu vận hành bên trong các ngôn ngữ lập trình nói chung, và đặc biệt là cách chúng được xử lý bên trong hệ sinh thái này nói riêng. Một làn sóng cuồng nộ và trào lưu mạnh mẽ đang càn quét qua cộng đồng mạng, xúi giục mọi người vội vã tháo chạy sang các phương pháp tiếp cận định kiểu tĩnh, mù quáng phụ thuộc vào các công cụ kiểm soát kiểu dữ liệu ngoại lai như TypeScript hay Flow. Rõ ràng, việc các kỹ sư dành thời gian để nghiên cứu sâu rộng hơn về hệ thống kiểu dữ liệu, cũng như thấu hiểu cặn kẽ cách thức mà bộ máy ngôn ngữ quản lý các luồng chuyển đổi kiểu là một yêu cầu chính đáng và cần thiết. Không thể phủ nhận rằng các công cụ kiểm soát kiểu dữ liệu này có thể đóng vai trò như một trợ thủ đắc lực, nhưng với một điều kiện tiên quyết mang tính sống còn: các kỹ sư đó bắt buộc phải trang bị sẵn cho mình một nền tảng kiến thức vững chắc về kiểu dữ liệu gốc rễ của ngôn ngữ và biết cách vận dụng chúng một cách khéo léo trước khi cầu viện đến công cụ.
Tuy nhiên, việc mù quáng chấp nhận một kết luận đầy tính quy chụp rằng hệ thống quản lý kiểu của JavaScript là tồi tệ, là rác rưởi, và chúng ta buộc phải tìm mọi cách để che đậy, vá víu nó bằng những giải pháp vá víu đến từ bên ngoài ranh giới của ngôn ngữ là một sự xúc phạm đối với tư duy kiến trúc. Chúng ta hoàn toàn không bị ép buộc phải ngoan ngoãn đi theo lối mòn của tư duy định kiểu tĩnh chỉ để chứng minh bản thân là những kỹ sư thông minh và viết ra được những hệ thống an toàn, vững chãi. Có vô số những con đường quang đãng khác, những giải pháp thay thế tinh tế hơn rất nhiều, nếu như bạn có đủ dũng khí để đi ngược lại đám đông cuồng nộ (against the grain), và thuận theo dòng chảy tự nhiên (with the grain) của chính bản thể ngôn ngữ.
Nếu đem ra tranh luận một cách sòng phẳng, trụ cột thứ ba này thậm chí còn nắm giữ một vị thế quan trọng hơn cả hai trụ cột trước đó, dựa trên một chân lý phũ phàng: tuyệt đối không có bất kỳ một chương trình JavaScript nào có thể thực thi thành công một tác vụ mang lại giá trị hữu dụng nếu như nó không biết cách đòn bẩy và thao tác chính xác với hệ thống kiểu giá trị nguyên bản, cũng như không làm chủ được cơ chế biến đổi (ép kiểu) luân chuyển các giá trị đó qua lại giữa các kiểu định dạng khác nhau. Ngay cả khi bạn là một tín đồ cuồng nhiệt, tôn thờ TypeScript hay Flow, bạn sẽ vĩnh viễn không bao giờ có thể vắt kiệt sức mạnh của những công cụ đó, hay đạt đến cảnh giới tối cao của các phương pháp lập trình nếu như bản thân bạn chưa từng đắm mình và làm quen sâu sắc với cách thức bộ máy cốt lõi của ngôn ngữ tự thân nó xoay xở và quản lý các kiểu giá trị dữ liệu như thế nào. Để thực sự khai sáng và đập tan những định kiến về hệ thống kiểu và ép kiểu, việc nghiền ngẫm Tập 4, Types & Grammar là không thể chối từ. Xin đừng hèn nhát lảng tránh phân vùng kiến thức này chỉ vì bạn đã bị tẩy não bởi những lời khuyên sáo rỗng, rập khuôn rằng chúng ta chỉ nên sử dụng toán tử === và ném mọi thứ phức tạp khác vào sọt rác. Nếu từ chối việc đào sâu và làm chủ trụ cột nền tảng này, kiến trúc hệ thống của bạn xây dựng nên sẽ vĩnh viễn nằm trên một nền móng lung lay, đầy khiếm khuyết và dễ dàng sụp đổ trước những bài toán phức tạp nhất.
Tương tác với dòng chảy tự nhiên của ngôn ngữ
Hành trình chinh phục hệ sinh thái ngôn ngữ JavaScript là một con đường dài đòi hỏi sự kiên định và một chiến lược học tập khôn ngoan. Lời khuyên vô giá nhất dành cho bạn trong suốt quá trình thẩm thấu phần còn lại của bộ sách là hãy luôn duy trì sự tỉnh thức và nhạy bén tối đa đối với khái niệm dòng chảy tự nhiên (the grain) của ngôn ngữ. Khái niệm này không chỉ giới hạn ở cách thức bộ máy thực thi vận hành ở tầng thấp nhất, mà nó còn bao hàm cả văn hóa, thói quen và những định kiến đang ăn sâu bám rễ trong cộng đồng kỹ sư toàn cầu.
Trước tiên, hãy đưa vào tầm ngắm phân tích cái dòng chảy tư duy phổ biến về cách thức mà đại đa số lập trình viên trên thế giới đang tiếp cận và thao tác với ngôn ngữ này. Có lẽ bạn đã phần nào cảm nhận được một sự thật trần trụi: bộ tài liệu này, ở vô số khía cạnh học thuật, đang lựa chọn một con đường vô cùng chông gai là cắt ngang, đi ngược lại hoàn toàn với cái dòng chảy đại chúng đó. Bằng tất cả sự tôn trọng cao nhất dành cho trí tuệ của độc giả, bộ sách này không chọn cách né tránh hay bưng bít, mà cam kết giải phẫu và phơi bày trọn vẹn mọi ngóc ngách, mọi cơ chế ẩn khuất nhất của ngôn ngữ, chứ không chỉ quẩn quanh vuốt ve những tính năng hào nhoáng, bề nổi và được ưa chuộng nhất. Niềm tin bất diệt được đặt ra là bạn hoàn toàn sở hữu đủ năng lực trí tuệ để hấp thụ và hoàn toàn xứng đáng được trang bị một khối lượng tri thức toàn diện, không bị cắt xén như vậy.
Thế nhưng, sự thật phũ phàng là những tri thức sâu sắc và nguyên bản này lại là thứ hàng hiếm mà bạn gần như tuyệt vọng trong việc tìm kiếm từ mớ bòng bong các tài liệu hướng dẫn trôi nổi ngoài kia. Điều này kéo theo một hệ quả mang tính rủi ro cao: khi bạn càng thấm nhuần, càng tuân thủ nghiêm ngặt các triết lý thiết kế từ bộ sách này – tức là bạn bắt đầu biết cách tư duy cẩn trọng, tự mình phân tích và đưa ra những quyết định kiến trúc sáng suốt nhất cho mã nguồn của mình – bạn sẽ càng trở nên dị biệt, càng nổi bật và tách rời khỏi sự tầm thường của đám đông. Sự dị biệt đó là một con dao hai lưỡi sắc bén. Chân lý không thể chối cãi là nếu bạn nuôi dưỡng tham vọng bứt phá, vươn lên khỏi một đám đông ù lì, bạn bắt buộc phải dũng cảm đập tan những khuôn mẫu hành xử tẻ nhạt mà đám đông đó vẫn đang cắm cúi làm theo. Đã có vô số những báo cáo thực tế cay đắng gửi về từ các độc giả: họ đã can đảm trích dẫn các quan điểm kiến trúc đột phá, những lời giải thích sâu sắc từ bộ sách này ngay giữa những cuộc phỏng vấn tuyển dụng sinh tử, để rồi nhận lại một cái tát thẳng thừng từ những vị giám khảo bảo thủ, tuyên bố rằng những ứng viên đó hoàn toàn sai lệch; và quả thực, cái giá phải trả cho sự dị biệt đó đôi khi là sự đánh mất những cơ hội việc làm tưởng chừng như đã nằm chắc trong tay.
Với tư cách là người dẫn đường, bộ sách này luôn nỗ lực đến mức tối đa để cung cấp những luồng thông tin chuẩn xác tuyệt đối, mang tính chất học thuật cao nhất về ngôn ngữ, phần lớn được chắt lọc trực tiếp từ chính bộ tài liệu đặc tả gốc. Song hành với những chân lý kỹ thuật đó, những quan điểm cá nhân, những triết lý định hướng về cách thức diễn giải và ứng dụng ngôn ngữ sao cho mang lại hiệu năng và lợi ích tối thượng nhất cho hệ thống cũng được lồng ghép một cách vô cùng đậm nét. Một ranh giới đạo đức nghề nghiệp luôn được giữ vững: tuyệt đối không bao giờ đánh tráo khái niệm, không biến quan điểm cá nhân thành chân lý bắt buộc, và cũng không bao giờ hạ thấp chân lý thành một quan điểm tùy chọn. Xuyên suốt quá trình đọc, bạn sẽ luôn được cung cấp đủ dữ kiện để phân định rạch ròi đâu là sự thật kỹ thuật, đâu là triết lý ứng dụng. Những sự thật kỹ thuật liên quan đến bản chất ngôn ngữ là những định lý thép, vĩnh viễn không mở cửa cho những cuộc tranh luận vô bổ. Một là bộ đặc tả có ghi chép quy định đó, hai là không. Nếu bạn cảm thấy bất mãn hay khó chịu với những gì mà bộ đặc tả quy định, hoặc không hài lòng với cách mà thông điệp đó được truyền tải, nơi duy nhất bạn nên tìm đến để khiếu nại chính là ủy ban kỹ thuật TC39! Nếu trong một cuộc phỏng vấn căng thẳng, và hội đồng đánh giá cố tình bóp méo sự thật, cáo buộc bạn sai lệch về mặt bản chất kỹ thuật, hãy yêu cầu họ ngay lập tức mở bộ tài liệu đặc tả ra để đối chứng công khai ngay tại bàn. Nếu những vị giám khảo đó tỏ thái độ ngoan cố, từ chối việc kiểm tra lại kiến thức của chính mình, thì đó là một tín hiệu vũ trụ cho thấy đó là một môi trường làm việc độc hại mà bạn hoàn toàn không nên hoang phí tài năng của mình vào đó.
Tuy nhiên, trong trường hợp bạn bị thuyết phục và quyết định đồng hành cùng những triết lý ứng dụng được đề xuất trong bộ sách này, bạn phải trang bị cho mình một tinh thần chiến binh, sẵn sàng đứng lên bảo vệ những lựa chọn kiến trúc đó bằng những luận điểm logic sắc bén, giải thích tường tận lý do tại sao bạn lại có niềm tin mãnh liệt vào cách tiếp cận đó. Đừng bao giờ hạ thấp bản thân trở thành một con vẹt chỉ biết nhại lại những gì đã đọc. Hãy biến những triết lý đó thành máu thịt của mình, hãy sở hữu chúng, và dũng cảm chiến đấu bảo vệ chúng. Và nếu như một vị đồng nghiệp, hay một nhà tuyển dụng mà bạn từng khao khát được cống hiến kiên quyết bác bỏ và bất đồng quan điểm, hãy quay gót bước đi một cách dứt khoát với một cái đầu ngẩng cao đầy tự hào. Hệ sinh thái JavaScript là một vùng đất bao la vĩ đại, và ở đó luôn dư thừa không gian cho vô số những con đường, những triết lý kiến trúc hoàn toàn khác biệt nhau cùng tồn tại và phát triển. Nói một cách ngắn gọn, đừng bao giờ để nỗi sợ hãi chùn bước khi bạn quyết định đi ngược lại với cái dòng chảy bảo thủ của đám đông, giống hệt như cái cách mà bộ tài liệu này và toàn bộ hệ thống giáo lý của nó đã kiên cường chống lại. Không một thế lực nào trên thế giới này có quyền năng áp đặt bạn phải sử dụng ngôn ngữ này như thế nào cho đúng; quyền quyết định tối thượng và duy nhất thuộc về bộ não của bạn. Sứ mệnh duy nhất ở đây là trao cho bạn một thanh gươm sắc bén là tri thức, trao quyền lực vào tay bạn để bạn có thể tự mình chém đứt những xiềng xích định kiến, tự mình đi đến những kết luận kiến trúc của riêng mình, bất chấp những kết luận đó có lập dị hay khác biệt đến mức độ nào đi chăng nữa.
Ở một khía cạnh hoàn toàn khác, có một cái dòng chảy mang tính sống còn mà bạn tuyệt đối phải tôn trọng, phân tích kỹ lưỡng và nương theo: đó chính là cái dòng chảy quy định cách thức bộ máy cốt lõi của ngôn ngữ vận hành ở tận cùng mức độ ngôn ngữ máy. Có vô số những mẫu thiết kế, những cấu trúc cú pháp được sinh ra để hoạt động một cách trơn tru, mạnh mẽ và hoàn toàn thuận theo tự nhiên bên trong hệ sinh thái này, miễn là bạn áp dụng đúng phương pháp và luyện tập đủ nhiều; song song với đó, cũng tồn tại vô số những trò lố bịch, những thủ thuật tồi tệ mà bạn tuyệt đối không bao giờ được phép thử nghiệm hay nhúng tay vào khi làm việc với ngôn ngữ này. Bạn có thể vận dụng trí thông minh của mình để ép buộc một chương trình JavaScript giả dạng, khoác lên mình một lớp áo cú pháp trông có vẻ na ná như một chương trình Java, C#, hay Perl được không? Thế còn ép nó giả vờ thành Python, Ruby, hay thậm chí là PHP thì sao? Chắc chắn rồi, với một mức độ ép buộc nhất định, bạn hoàn toàn có thể làm được điều đó. Nhưng câu hỏi nhức nhối đặt ra là: Bạn có thực sự nên làm điều ngu ngốc đó hay không?
Câu trả lời là một tiếng Không đầy dứt khoát, việc cố tình bóp méo bản sắc của ngôn ngữ là một hành động phản kiến trúc. Con đường quang đãng duy nhất là bạn phải học cách thấu hiểu, yêu thương và dang tay ôm trọn lấy cái chất riêng biệt của JavaScript, và phải nỗ lực đến cùng để nhào nặn nên những chương trình mang đậm đà bản sắc của JavaScript nhất có thể trong giới hạn của sự thực dụng. Sẽ có những kẻ thiển cận buông lời chê bai rằng việc giữ nguyên bản sắc đó đồng nghĩa với việc dung túng cho một phong cách lập trình lỏng lẻo, bừa bãi và vô tổ chức, nhưng luận điểm đó là một sự vu khống trắng trợn. Sự thật là, ngôn ngữ này sở hữu một kho tàng khổng lồ các mẫu thiết kế kiến trúc và những thành ngữ lập trình độc đáo, những thứ mà chỉ cần nhìn thoáng qua là có thể nhận diện ngay lập tức là chuẩn JavaScript; và việc lướt đi một cách mượt mà trên chính cái dòng chảy bản sắc đó chính là con đường cao tốc rộng mở nhất dẫn đến một sự thành công rực rỡ và bền vững.
Cuối cùng, và cũng có lẽ là cái dòng chảy mang tính thực tiễn khốc liệt nhất mà bạn phải học cách nhận diện và đối phó: đó là cái dòng chảy quy định cách thức mà các hệ thống mã nguồn hiện tại bạn đang phải bảo trì, cũng như cách thức tư duy của những đồng nghiệp đang ngồi làm việc ngay cạnh bạn, đang xử lý và giải quyết vấn đề. Đừng bao giờ ngây thơ đến mức đọc xong những cuốn sách này, mang một cái đầu nóng rực lửa về công ty và cố gắng lật đổ, thay đổi toàn bộ cái dòng chảy văn hóa đó trong các dự án hiện tại chỉ sau một đêm. Một cuộc cách mạng bạo lực như vậy được đảm bảo 100% sẽ chuốc lấy một thất bại thảm hại và đau đớn.
Sự thay đổi vĩ đại đòi hỏi một chiến thuật du kích: bạn phải dịch chuyển những khối đá khổng lồ này từng chút, từng chút một, bền bỉ mài mòn theo dòng chảy của thời gian. Hãy dồn tâm sức vào việc xây dựng sự đồng thuận, khơi gợi nhận thức của các kỹ sư đồng nghiệp về việc tại sao việc đào xới lại những đống mã cũ và đánh giá lại một phương pháp tiếp cận kiến trúc lại là một nhiệm vụ mang tính sống còn đối với sự sống còn của dự án. Nhưng hãy hành động một cách tinh tế: chỉ đưa ra ánh sáng một chủ đề kỹ thuật nhỏ xíu tại một thời điểm, và hãy để cho những minh chứng hùng hồn từ việc so sánh hiệu năng, độ sạch của mã nguồn trước-và-sau khi thay đổi làm công việc thuyết phục thay bạn. Hãy triệu tập toàn bộ trí tuệ của nhóm lại cùng nhau mổ xẻ, tranh luận nảy lửa, và kiên quyết thúc đẩy mọi quyết định phải được đưa ra dựa trên nền tảng của sự phân tích logic sắc bén và những bằng chứng không thể chối cãi trích xuất trực tiếp từ mã nguồn, thay vì đầu hàng trước sức ỳ khủng khiếp của một câu cửa miệng chết chóc: nhưng mấy ông kỹ sư trưởng hồi xưa giờ toàn làm theo cách đó mà. Đó chính là lời khuyên mang tính chiến lược và quý giá bậc nhất có thể được trao truyền lại để bảo vệ bạn trên con đường chinh phục ngôn ngữ đầy bão táp này. Hãy không ngừng nghỉ, luôn luôn săn lùng những phương pháp tiếp cận ưu việt hơn để vắt kiệt những tài nguyên mà ngôn ngữ cung cấp, nhằm mục đích kiến tạo nên những khối lượng mã nguồn trong vắt và dễ thẩm thấu nhất. Bất kỳ một linh hồn nào phải dính líu đến việc bảo trì đoạn mã của bạn trong tương lai, bao gồm cả chính bản thể tương lai của bạn, sẽ phải cúi đầu gửi đến bạn những lời cảm tạ sâu sắc nhất!