Lưu ý rằng tôi đang dựa trên tất cả các lập luận của mình về các trường hợp sử dụng trong thế giới thực. Các đối số không thể được sao lưu bằng một ví dụ về việc sử dụng trong một ứng dụng thực tế, đầy đủ, thú vị, hữu ích là không hợp lệ. Tôi đã thấy những "bản trình diễn ngôn ngữ" nhỏ mà mọi người khác có, tôi đã thấy các bài đăng trên blog mô tả chi tiết cách các nguyên mẫu và kiểu gõ động tạo ra một số ví dụ nhỏ tầm thường ngắn hơn vài dòng so với C #, nhưng những thứ đó đơn giản là không liên quan cho đến những vấn đề bạn gặp phải khi viết
mã thật chứ không phải micro-demos và đồ chơi. Vì vậy, đây là sự hiểu biết của tôi với JS:
a) Phép thuật 'này'. Đây là cái này, trừ khi cái này là cái kia. JavaScript thúc đẩy bạn sử dụng các hàm ẩn danh ở mọi nơi, ngoại trừ chúng luôn mất bối cảnh thích hợp cho biến 'this', do đó cuối cùng bạn sẽ có mã ngớ ngẩn như "var _this = this" ở khắp mọi nơi và sau đó sử dụng nó bên trong cuộc gọi lại của bạn hoặc các chức năng khác. Đôi khi tôi thề rằng số lượng chức năng tôi quản lý để viết mà không sử dụng tên 'cái này' thực sự nhỏ hơn số lượng thực hiện.
b) 1 + "1" - 1 = 10. Ngoài ra, "1" + 0 = "10". Có, điều này thực sự đã gây ra lỗi cho các ứng dụng của chúng tôi, trong đó dữ liệu được dự kiến là một số được tải từ tệp JSON dưới dạng chuỗi do lỗi trong ứng dụng khác và kết quả không tốt. Tất cả mã tải của chúng tôi phải được cập nhật để thêm một tấn chuyển đổi loại ở mọi nơi. Khi tôi cần một số nào đó để trở thành một số tôi thực sự hoảng hốt hoàn toàn muốn nó là một số, không phải là một chuỗi hoặc một đối tượng hoặc null hoặc bất cứ điều gì khác. Lua, rất giống với JavaScript ở hầu hết các khía cạnh, đã khắc phục vấn đề này bằng cách không bị chậm phát triển đủ để sử dụng cùng một toán tử để thêm và nối chuỗi.
c) Toàn cầu theo các biến mặc định. Vì vậy, ngay cả khi bạn đưa ra lập luận rằng việc gõ động chỉ "dễ dàng" hơn vì bạn không phải suy nghĩ về các khai báo biến, JavaScript sẽ ném đối số đó ra ngoài cửa sổ bằng cách đặt 'var' trước các số nhận dạng mới ở mọi nơi . Và sau đó nó âm thầm vít bạn nếu bạn quên.
d) Nguyên mẫu thay vì các lớp. Có rất ít ứng dụng JavaScript trong thế giới thực tồn tại mà không cắm vào hệ thống lớp của riêng chúng để khắc phục sự vô dụng vốn có của các nguyên mẫu trong kiến trúc ứng dụng lớn. Các ứng dụng tương tự đó sử dụng các nguyên mẫu tối thiểu để mở rộng các loại JavaScript cơ bản và chỉ vì JS được thiết kế kém đến mức ngay cả hai loại tích hợp thú vị mà nó đi kèm cũng thiếu một nửa các tính năng mà bạn mong đợi.
e) Không có khả năng tạo các loại giá trị truyền qua. Đây thực sự là một vấn đề thường gặp ở mọi ngôn ngữ ngoài C ++ / D. Đối với những người sử dụng JavaScript để viết ứng dụng WebGL, hãy xem tất cả các thư viện đại số tuyến tính cho JavaScript. Trong các ứng dụng 3D, bạn hầu như sử dụng vectơ thường xuyên hơn so với vô hướng. Hãy tưởng tượng nếu mọi số nguyên trong ứng dụng của bạn được truyền bằng tham chiếu, sao cho "a = 1; b = a; b ++" làm cho cả a và b bằng 2. Mỗi vectơ ba thành phần nhỏ là một đối tượng đầy đủ. Chúng được chuyển qua tham chiếu (trên thực tế, nguồn gốc của gần một nửa lỗi trong trò chơi WebGL của chúng tôi). Chúng tồn tại với số lượng lớn, được phân bổ thành từng đống và được thu gom rác, điều này gây áp lực lớn lên GC, điều này có thể và dẫn đến tạm dừng GC trong các trò chơi WebGL đơn giản, trừ khi nhà phát triển nhảy qua các vòng phức tạp lố bịch để tránh tạo ra các vectơ mới ở tất cả những nơi hợp lý để tạo ra các vectơ mới. Bạn không thể có quá tải toán tử, do đó bạn có các biểu thức rất lớn và xấu để thực hiện các thao tác cơ bản. Truy cập các thành phần riêng lẻ là chậm. Các đối tượng không được đóng gói nguyên bản và do đó cực kỳ chậm để đẩy vào bộ đệm đỉnh, trừ khi bạn triển khai chúng dưới dạng phiên bản Float32Array, điều này làm lẫn lộn các trình tối ưu hóa của cả V8 và SpiderMonkey hiện tại. Tôi đã đề cập đến họ thông qua tham chiếu? Truy cập các thành phần riêng lẻ là chậm. Các đối tượng không được đóng gói nguyên bản và do đó cực kỳ chậm để đẩy vào bộ đệm đỉnh, trừ khi bạn triển khai chúng dưới dạng phiên bản Float32Array, điều này làm lẫn lộn các trình tối ưu hóa của cả V8 và SpiderMonkey hiện tại. Tôi đã đề cập đến họ thông qua tham chiếu? Truy cập các thành phần riêng lẻ là chậm. Các đối tượng không được đóng gói nguyên bản và do đó cực kỳ chậm để đẩy vào bộ đệm đỉnh, trừ khi bạn triển khai chúng dưới dạng phiên bản Float32Array, điều này làm lẫn lộn các trình tối ưu hóa của cả V8 và SpiderMonkey hiện tại. Tôi đã đề cập đến họ thông qua tham chiếu?
f) Không tích hợp bao gồm hoặc yêu cầu chức năng. Nghiêm túc, vẫn thế. Các thư viện của bên thứ ba tồn tại nhưng hầu như tất cả chúng đều có một số lỗi hoặc lỗi khác, không ít trong số đó là vấn đề bộ nhớ đệm khó hiểu trong ít nhất Chrome khiến việc phát triển thực sự trở nên khó khăn.
g) Gõ động. Vâng, tôi sẵn sàng bắt đầu cuộc tranh luận đó. Bạn bắt đầu nhận thấy nó nhiều nhất là lần thứ hai bạn dừng viết các ứng dụng Web hoặc trang web nhỏ và bắt đầu viết các ứng dụng lớn trong đó bạn thực sự có dữ liệu tồn tại lâu hơn một lần nhấp chuột hoặc chu kỳ yêu cầu / phản hồi: thêm loại đối tượng sai vào một mảng để xử lý sau và gặp sự cố sau đó từ một phương thức hoặc thành viên bị thiếu trong một đoạn mã hoàn toàn khác so với lỗi thực tế. Thời gian vui vẻ. Vâng, Java làm cho gõ tĩnh có vẻ xấu. Không, Java / C # / C ++ không phải là cách duy nhất và duy nhất để thực hiện gõ tĩnh. Gõ suy luận, ràng buộc giao diện ngầm, v.v. cung cấp cho bạn tất cả các ưu điểm "dễ xử lý và không có nhiều thao tác bàn phím" của việc gõ động mà không gặp phải tất cả các lỗi. Ngôn ngữ Web phổ biến thứ hai - ActionScript 3 - được gõ tĩnh, trên thực tế, mặc dù khác với JS / ECMAScript. Bên cạnh đó, tôi nhận được nhiều sự cố hơn từ các ứng dụng Python trên máy tính để bàn Fedora của tôi so với các ứng dụng C / C ++ (thực ra, không có ứng dụng C / C ++ nào trên máy tính để bàn của tôi, bây giờ tôi nghĩ về nó). Thiếu ngoại lệ thành viên == để phát triển và duy trì ứng dụng dễ dàng hơn nhiều, phải không?
h) Tốc độ. Đúng vậy, đã có một số lượng lớn nỗ lực lố bịch của một số lượng lớn các nhà phát triển siêu lừa đảo đưa vào thời gian chạy ngôn ngữ để làm cho JS nhanh gần một nửa so với trình biên dịch C cấp thấp mà một sinh viên đại học duy nhất có thể viết trong một vài tháng. Và LuaJIT ở cùng một nhóm với JS về các hạn chế ngôn ngữ cơ bản nhưng vẫn quản lý để làm tốt hơn mọi triển khai JavaScript. Những người không hiểu tất cả các tối ưu hóa JS trong V8 hoặc như vậy thực sự là gì làm gìmuốn tuyên bố rằng JS có thể làm những điều đáng kinh ngạc về tốc độ, nhưng thực tế là tất cả những tối ưu hóa đó về cơ bản chỉ là "rất cố gắng phân tích mã để tìm ra các loại cho các biến và sau đó biên dịch nó giống như một kiểu gõ hơi chậm trình biên dịch của ngôn ngữ sẽ làm điều đó. " Ồ, và có dấu vết, nhưng sau đó, dấu vết cũng hoạt động trên các ngôn ngữ được nhập tĩnh (và hoạt động tốt hơn do không cần bộ bảo vệ loại trong mã máy được tạo). Trên thực tế, không có một trong những tối ưu hóa whizbang nào được phát minh bởi hoặc cho JS; hầu hết được lấy từ các JVM nghiên cứu (Java là xấu xa!) hoặc các ngôn ngữ OOP cổ điển (các nguyên mẫu là tuyệt vời!).
i) Không có IntelliSense thậm chí có thể. Bạn muốn xem phương thức nào tồn tại trên biến đó mà bạn đã có trên dòng 187 của foo.js trong trình soạn thảo văn bản của mình? Quá tệ. Đi theo dõi mã cho đến khi bạn tìm ra nơi nó được khởi tạo, sau đó truy tìm mã để tìm hiểu nguyên mẫu của nó có gì trên đó. Và sau đó hy vọng không có mã tự động thay đổi nguyên mẫu phía sau lưng của bạn. Trên thực tế, chỉ cần chạy nó trong trình duyệt và đặt các điểm dừng, bởi vì việc tìm ra bất cứ điều gì hữu ích về giá trị theo bất kỳ cách nào khác về cơ bản là không thể đối với bất kỳ cơ sở mã hóa nào lớn hơn toy_web_app.html các trang web mà người xin lỗi JavaScript sử dụng để tôn vinh sự dễ dàng và đơn giản của JavaScript. Một số trình soạn thảo mã cố gắng thực sự khó khăn để làm tốt hơn và gần như là một loại thành công cho các trường hợp thực sự đơn giản, đôi khi, một lần.
j) Không có lợi thế. JavaScript thậm chí không đặc biệt so với ngôn ngữ gõ động khác. Nó hoàn toàn không có khả năng làm bất cứ điều gì thú vị mà Lua, Python, Ruby, v.v. Không có cách triển khai JS nào nhanh hơn LuaJIT hoặc PyPy hoặc các triển khai JIT nâng cao khác của động lực khác ngôn ngữ. JS không có điểm cộng nào so với các ngôn ngữ phổ biến khác. Ồ, ngoại trừ nó chạy tự nhiên trong trình duyệt Web mà không cần plugin. Đó là lý do duy nhất trên thế giới tại sao nó rất phổ biến. Trong thực tế, đó là lý do duy nhất nó sự kiện tồn tại. Nếu ai đó 10 năm trước chỉ nghĩ: "quái gì, hãy bỏ một ngôn ngữ được thiết kế tốt và có sẵn vào trình duyệt của chúng tôi và khiến những kẻ khác làm điều tương tự thay vì bắt mọi người sử dụng hackjob nhỏ bé ngốc nghếch này mà NetScape nghĩ ra , "Web sẽ khác rất nhiều (tốt hơn) ngày hôm nay. Chỉ cần tưởng tượng về tương lai nếu Chrome bỏ Python vào Chrome như một ngôn ngữ được hỗ trợ. Hoặc thực tế, hãy tưởng tượng điều này: Google bỏ C / C ++ vào Chrome làm ngôn ngữ được hỗ trợ (http://code.google.com.vn/p/nativeclient/).