Tôi muốn thêm một câu trả lời cho câu hỏi này vì tôi đã lướt qua một số Java tốt, xấu nhưng chủ yếu là xấu gần đây và tôi có một khối lượng hoàn toàn mới về sự khái quát quá mức về các nhà phát triển Java và Java so với JS và Các nhà phát triển JS thực sự có thể dựa trên một cái gì đó mơ hồ giống với sự thật hữu ích.
Có những IDE nhưng nó có thể hữu ích để hiểu tại sao không có nhiều
Bây giờ tôi đã dùng thử Webstorm và thấy mình bị cuốn hút vào sự phát triển của Node và nó không tệ đến mức tôi thực sự đã mua nó nhưng tôi vẫn có xu hướng mở các tệp js trong Scite thường xuyên hơn WS. Lý do cho điều này là vì bạn có thể làm được nhiều hơn với rất ít trong JS nhưng cũng vì công việc UI mang lại phản hồi ngay lập tức, các công cụ phát triển trình duyệt (đặc biệt là Chrome và Firebird) thực sự khá xuất sắc và (chiếm các bối cảnh không phải trình duyệt ) chạy lại mã đã thay đổi là nhanh chóng và dễ dàng mà không cần một bước biên dịch.
Một điều nữa tôi khá bị thuyết phục là các IDE về cơ bản tạo ra nhu cầu của riêng chúng bằng cách kích hoạt mã cẩu thả mà bạn thực sự không thể mua được trong JavaScript. Bạn muốn tìm hiểu cách chúng tôi quản lý trong JS? Có thể giúp bắt đầu bằng cách cố gắng viết một cái gì đó không tầm thường trong Java mà không cần IDE và chú ý đến những điều bạn phải bắt đầu làm và suy nghĩ để thực sự có thể duy trì / sửa đổi mã mà không cần IDE di chuyển phía trước. IMO, những điều tương tự vẫn rất quan trọng để viết mã có thể duy trì cho dù bạn có IDE hay không. Nếu tôi phải viết một chương trình giảng dạy lập trình 4 năm, nó sẽ không cho phép bạn chạm vào IDE trong hai năm đầu tiên vì không muốn các công cụ và phụ thuộc bị xoắn.
Kết cấu
Các nhà phát triển JS có kinh nghiệm xử lý các ứng dụng phức tạp có thể và thực hiện cấu trúc mã của họ. Trên thực tế, có một điều chúng ta có xu hướng phải trở nên tốt hơn với một lịch sử ban đầu thiếu IDE để đọc mã cho chúng ta nhưng cũng bởi vì các ngôn ngữ biểu cảm mạnh mẽ có thể diễn đạt mạnh mẽ các mã hóa thảm họa hoàn toàn không thể nhận ra rất nhanh nếu bạn không mã hóa một cách chu đáo.
Tôi thực sự đã có một đường cong học tập khá dốc để hiểu cơ sở mã Java của chúng tôi gần đây cho đến khi cuối cùng tôi nhận ra rằng không có cái nào là OOP thích hợp. Các lớp học không có gì khác ngoài các gói phương pháp liên quan lỏng lẻo làm thay đổi dữ liệu có sẵn trên toàn cầu trong các hạt đậu hoặc DTO hoặc getters / setters tĩnh. Về cơ bản, đó chính là con thú cũ mà OOP phải thay thế. Vì vậy, tôi ngừng tìm kiếm và suy nghĩ về mã về cơ bản. Tôi chỉ học các phím tắt và lần theo các mớ hỗn độn và mọi thứ diễn ra suôn sẻ hơn nhiều. Vì vậy, nếu bạn chưa có thói quen này, hãy suy nghĩ nhiều hơn về OOD.
Một ứng dụng JS có cấu trúc tốt ở mức cao nhất sẽ có xu hướng bao gồm các hàm phức tạp (ví dụ jQuery) và các đối tượng tương tác với nhau. Tôi sẽ lập luận rằng dấu hiệu của một ứng dụng có cấu trúc tốt, dễ bảo trì trong bất kỳ ngôn ngữ nào là nó hoàn toàn dễ đọc cho dù bạn đang xem nó với IDE hay Notepad ++. Đó là một trong những lý do chính khiến tôi hết sức phê phán việc tiêm phụ thuộc và TDD thử nghiệm đầu tiên được đưa ra đến mức cực đoan.
Và cuối cùng, buông bỏ các lớp học. Tìm hiểu thừa kế nguyên mẫu. Nó thực sự khá thanh lịch dễ thực hiện khi bạn thực sự cần thừa kế. Tuy nhiên, tôi thấy các cách tiếp cận tổng hợp có xu hướng hoạt động tốt hơn nhiều trong JS, và cá nhân tôi bắt đầu bị bệnh và mắc chứng sợ hãi đêm EXTJS bất cứ khi nào tôi thấy nhiều hơn một hoặc hai cấp độ kế thừa diễn ra trong bất kỳ ngôn ngữ nào.
Nguyên tắc cốt lõi đầu tiên
Tôi đang nói về những thứ cốt lõi mà tất cả các thực tiễn tốt khác nên xuất phát từ: DRY, YAGNI, nguyên tắc ít ngạc nhiên nhất, tách biệt các miền vấn đề, viết lên giao diện và viết mã rõ ràng của con người là cốt lõi cá nhân của tôi. Bất cứ điều gì phức tạp hơn một chút ủng hộ việc từ bỏ các thực tiễn đó đều phải được coi là Kool Aid trong bất kỳ ngôn ngữ nào, nhưng đặc biệt là một ngôn ngữ như JavaScript, nơi rất dễ để lại một di sản mã rất khó hiểu cho người tiếp theo. Chẳng hạn, khớp nối lỏng lẻo là một thứ tuyệt vời cho đến khi bạn mang nó đi xa đến mức bạn thậm chí không thể biết được sự tương tác giữa các vật thể đang diễn ra ở đâu.
Đừng sợ gõ động
Không có nhiều loại cốt lõi trong JavaScript. Đối với hầu hết các phần, các quy tắc truyền động là thực tế và đơn giản nhưng nó trả tiền để tìm hiểu chúng để bạn có thể học tốt hơn để quản lý luồng dữ liệu mà không cần phôi và các thói quen xác thực vô nghĩa. Tin tôi đi Các loại nghiêm ngặt rất tốt cho hiệu năng và phát hiện các vấn đề khi biên dịch nhưng chúng không bảo vệ bạn khỏi mọi thứ.
Tìm hiểu các crap ra khỏi các hàm và đóng của JS
Các chức năng hạng nhất của JS được cho là lý do chính khiến JS giành giải "Ngôn ngữ duy nhất đáng để chạm vào web phía khách hàng với giải thưởng." Và vâng, thực sự đã có sự cạnh tranh. Chúng cũng là một tính năng trung tâm của JS. Chúng tôi xây dựng các đối tượng với chúng. Tất cả mọi thứ là phạm vi chức năng. Và chúng có các tính năng tiện dụng. Chúng ta có thể kiểm tra params thông qua từ khóa argument. Chúng ta có thể tạm thời gắn và bắn chúng trong bối cảnh là phương thức của các đối tượng khác. Và họ làm cho các cách tiếp cận theo hướng sự kiện đến những thứ khó hiểu dễ thực hiện. Nói tóm lại, họ đã biến JS thành một con thú tuyệt đối trong việc giảm độ phức tạp và điều chỉnh các cách triển khai khác nhau của chính JS (nhưng chủ yếu là API DOM) ngay tại nguồn.
Đánh giá lại các mô hình / thực tiễn trước khi áp dụng
Các hàm hạng nhất và các kiểu động tạo ra rất nhiều các mẫu thiết kế phức tạp hơn hoàn toàn vô nghĩa và cồng kềnh trong JS. Tuy nhiên, một số mẫu đơn giản hơn lại cực kỳ hữu ích và dễ thực hiện do tính chất rất linh hoạt của JS. Bộ điều hợp và trang trí đặc biệt hữu ích và tôi đã tìm thấy các singletons hữu ích cho các nhà máy phụ tùng ui phức tạp cũng đóng vai trò là người quản lý sự kiện cho các yếu tố ui mà họ xây dựng.
Theo dõi sự dẫn dắt của ngôn ngữ và làm nhiều hơn với ít hơn
Tôi tin rằng một trong những honchos đứng đầu Java đưa ra lập luận ở đâu đó rằng tính dài dòng thực sự là một tính năng tích cực giúp mã dễ hiểu hơn cho tất cả các bên. Chuyện nhảm. Nếu đó là sự thật, hợp pháp sẽ dễ đọc hơn. Chỉ người viết mới có thể làm cho những gì họ viết dễ hiểu hơn và bạn chỉ có thể làm điều đó bằng cách thỉnh thoảng đặt mình vào vị trí của người kia. Vì vậy, hãy nắm lấy hai quy tắc này. 1. Càng trực tiếp và rõ ràng càng tốt. 2. Đến điểm chết tiệt rồi. Chiến thắng là mã rõ ràng, súc tích là những mệnh lệnh có độ lớn dễ hiểu và duy trì hơn so với thứ mà bạn phải đi qua hai mươi lăm lớp để có được từ trình kích hoạt đến hành động mong muốn thực tế. Hầu hết các mẫu ủng hộ loại điều đó trong các ngôn ngữ chặt chẽ hơn trên thực tế là cách giải quyết cho những hạn chế mà JavaScript không có.
Mọi thứ đều dễ uốn và được rồi
JS có lẽ là một trong những ngôn ngữ bảo hộ ít được sử dụng phổ biến nhất. Ôm lấy đó. Nó hoạt động tốt. Chẳng hạn, bạn có thể viết các đối tượng với các vars "private" liên tục không thể truy cập bằng cách khai báo các vars thông thường trong hàm constructor và tôi thường xuyên làm điều này. Nhưng đó không phải là để bảo vệ mã của tôi hoặc người dùng mã "khỏi chính họ" (họ chỉ có thể thay thế nó bằng phiên bản của chính họ trong thời gian chạy). Nhưng đúng hơn là để báo hiệu ý định bởi vì giả định rằng anh chàng kia đủ khả năng để không muốn thu thập bất kỳ sự phụ thuộc nào và sẽ thấy rằng bạn không có ý định trực tiếp có lẽ vì lý do chính đáng.
Không có giới hạn kích thước, chỉ có miền vấn đề
Vấn đề lớn nhất mà tôi gặp phải với tất cả các cơ sở mã Java mà tôi đã thấy là sự dư thừa các tệp lớp. Trước hết RẮN chỉ là một sự lặp lại khó hiểu về những gì bạn nên biết về OOP. Một lớp nên xử lý một tập hợp cụ thể các vấn đề liên quan. Không một vấn đề với một phương pháp. Đó chỉ là việc sử dụng mã func-spaghetti C chuỗi cũ xấu chỉ với việc thêm tất cả cú pháp lớp vô nghĩa để khởi động. Không có giới hạn kích thước hoặc phương pháp. Nếu nó có ý nghĩa để thêm một cái gì đó vào một hàm hoặc lớp hoặc hàm tạo đã dài, thì nó có ý nghĩa. Lấy jQuery. Đó là toàn bộ bộ công cụ có độ dài thư viện trong một hàm duy nhất và không có gì sai với điều đó. Việc chúng ta có cần jQuery hay không là tranh luận hợp lý nhưng về mặt thiết kế,
Nếu Java là tất cả những gì bạn biết, hãy tìm hiểu một cái gì đó với một cú pháp không dựa trên C
Khi tôi bắt đầu nhắn tin với Python vì tôi thích những gì tôi nghe về Django, tôi đã học cách bắt đầu tách cú pháp khỏi thiết kế ngôn ngữ. Kết quả là, việc hiểu Java và C trở nên dễ dàng hơn khi là một phần của các phần thiết kế ngôn ngữ của họ thay vì tổng của những điều họ làm khác nhau với cùng một cú pháp. Một tác dụng phụ tuyệt vời là bạn càng hiểu các ngôn ngữ khác về mặt thiết kế, bạn sẽ càng hiểu rõ hơn về điểm mạnh / điểm yếu của ngôn ngữ mà bạn biết rõ nhất qua sự tương phản.
Phần kết luận
Bây giờ, xem xét tất cả điều đó, hãy nhấn tất cả các điểm vấn đề của bạn:
- Không có cách nào ngay lập tức tìm điểm nhập của hàm (ngoài tìm kiếm văn bản đơn giản, sau đó có thể dẫn đến các tìm kiếm tiếp theo cho các phương thức tiếp tục phân cấp cuộc gọi, sau hai hoặc ba trong số đó bạn đã quên nơi bạn bắt đầu)
Chrome và Fireorms thực sự có tính năng theo dõi cuộc gọi. Nhưng cũng thấy quan điểm của tôi về cấu trúc và giữ cho mọi thứ ngắn gọn và trực tiếp. Bạn càng có thể nghĩ về ứng dụng của mình khi các cấu trúc được đóng gói tốt hơn tương tác với nhau, thì càng dễ dàng nhận ra lỗi của nó là gì khi gặp sự cố. Tôi cũng nói điều này đúng với Java. Chúng tôi có các hàm tạo giống như lớp hoàn toàn có thể phục vụ cho các mối quan tâm OOP truyền thống.
function ObjectConstructor(){
//No need for an init method.
//Just pass in params and do stuff inside for instantiation behavior
var privateAndPersistent = true;
//I like to take advantage of function hoisting for a nice concise interface listing
this.publicAndPointlessEncapsulationMurderingGetterSetter
= publicAndPointlessEncapsulationMurderingGetterSetter;
//Seriously though Java/C# folks, stop with the pointless getter/setters already
function publicAndPointlessEncapsulationMurderingGetterSetter(arg){
if(arg === undefined){
return privateAndPersistent;
}
privateAndPersistent = arg;
}
}
ObjectConstructor.staticLikeNonInstanceProperty = true;
var instance = new ObjectConstructor();//Convention is to capitalize constructors
Trong mã của tôi, tôi gần như không bao giờ sử dụng các đối tượng bằng chữ {}
như các thành phần ứng dụng cấu trúc vì chúng không thể có các vars nội bộ (riêng tư) và thay vào đó thích dành chúng để sử dụng làm cấu trúc dữ liệu. Điều đó giúp đặt ra một kỳ vọng duy trì sự rõ ràng của ý định. (nếu bạn thấy curlies, đó là dữ liệu, không phải là một thành phần của kiến trúc ứng dụng).
- Các tham số được truyền vào các hàm, không có cách nào biết các thuộc tính và hàm nào có sẵn trên tham số đó (ngoài việc thực sự chạy chương trình, điều hướng đến điểm mà hàm được gọi và sử dụng console.logs để xuất tất cả các thuộc tính có sẵn)
Một lần nữa, xem các công cụ trình duyệt hiện đại. Nhưng ngoài ra, tại sao lại chạy chương trình như vậy? Tải lại là thứ mà một nhà phát triển web phía khách hàng thường truy cập cứ sau vài phút bởi vì bạn hoàn toàn không mất gì để làm điều đó. Đây là một lần nữa, một điểm khác mà cấu trúc ứng dụng có thể hữu ích nhưng đó là một sự đánh đổi ngược lại của JS mà bạn phải chạy xác thực của riêng mình khi thực thi các hợp đồng là rất quan trọng (điều mà tôi chỉ làm ở các điểm cuối tiếp xúc với những điều khác mà cơ sở mã hóa của tôi không làm được kiểm soát). IMO, sự đánh đổi là giá trị lợi ích.
- Việc sử dụng phổ biến các hàm ẩn danh như các cuộc gọi lại, thường dẫn đến một chuỗi các đường dẫn mã khó hiểu, mà bạn không thể điều hướng nhanh chóng.
Vâng, đó là xấu trên bất cứ điều gì không tầm thường. Đừng làm vậy. Đặt tên cho các chức năng của bạn trẻ em. Nó cũng dễ dàng hơn để theo dõi mọi thứ. Bạn có thể xác định, đánh giá (bắt buộc phải gán) và gán một hàm tầm thường đơn giản phù hợp với:
doSomethingWithCallback( (function callBack(){}) );
Bây giờ Chrome sẽ có tên cho bạn khi bạn truy tìm các cuộc gọi. Đối với func không tầm thường, tôi sẽ xác định nó bên ngoài cuộc gọi. Cũng lưu ý rằng các hàm anonoymous được gán cho một biến vẫn ẩn danh.
- Và chắc chắn, JSLint đã bắt được một số lỗi trước khi chạy, nhưng thậm chí điều đó không hữu ích bằng việc có các đường lượn sóng màu đỏ dưới mã của bạn trực tiếp trong trình duyệt.
Tôi không bao giờ chạm vào những thứ. Crockford đã đưa ra một số điều tốt cho cộng đồng nhưng JSLint vượt qua các ưu tiên về phong cách và đề xuất các yếu tố nhất định của JavaScript là những phần không tốt vì lý do đặc biệt tốt, IMO. Chắc chắn bỏ qua rằng một điều về các lớp regEx và phủ định theo sau là * hoặc +. Ký tự đại diện hoạt động kém hơn và bạn có thể dễ dàng hạn chế sự lặp lại với {}. Ngoài ra, bỏ qua bất cứ điều gì ông nói về các nhà xây dựng chức năng. Bạn có thể dễ dàng gói chúng trong một func của nhà máy nếu từ khóa mới làm phiền bạn. CSSLint (không phải của Crockford) thậm chí còn tồi tệ hơn trên mặt trận tư vấn tồi. Luôn luôn lấy những người tham gia nói nhiều với một hạt muối. Đôi khi tôi thề rằng họ chỉ tìm cách thiết lập quyền lực hoặc tạo ra tài liệu mới.
Và một lần nữa, bạn phải học những gì bạn đã học được với mối quan tâm thời gian chạy này mà bạn có. (đó là một lỗi phổ biến mà tôi đã thấy với rất nhiều nhà phát triển Java / C #) Nếu thấy lỗi trong thời gian chạy vẫn làm phiền bạn 2 năm sau, tôi muốn bạn ngồi xuống và spam tải lại trong trình duyệt cho đến khi nó chìm vào. không phải là phân chia thời gian biên dịch / thời gian chạy (dù sao cũng không thể nhìn thấy được - JS hiện đang chạy trên JIT). Không chỉ ổn khi phát hiện ra lỗi trong thời gian chạy, nó cực kỳ có lợi để tải lại spam dễ dàng và rẻ tiền và phát hiện ra lỗi tại mọi điểm dừng bạn gặp phải.
Và tải crack trên các công cụ phát triển Chrome đó. Chúng được tích hợp trực tiếp vào webkit. Nhấp chuột phải vào Chrome. Kiểm tra nguyên tố. Khám phá các tab. Có rất nhiều sức mạnh gỡ lỗi ở đó với khả năng thay đổi mã trong bảng điều khiển trong thời gian chạy là một trong những tùy chọn mạnh mẽ nhất nhưng ít rõ ràng nhất. Tuyệt vời để thử nghiệm quá.
Trên một lưu ý liên quan, lỗi là bạn bè của bạn. Đừng bao giờ viết một tuyên bố bắt trống. Trong JS, chúng tôi không che giấu hoặc chôn vùi lỗi (hoặc ít nhất là chúng tôi không nên ho YUI / ho ). Chúng tôi tham dự với họ. Bất cứ điều gì ít hơn sẽ dẫn đến đau gỡ lỗi. Và nếu bạn viết một câu lệnh bắt để ẩn các lỗi tiềm ẩn trong sản xuất thì ít nhất hãy âm thầm ghi lại lỗi và ghi lại cách truy cập nhật ký.