Crockford đã làm rất nhiều để phổ biến các kỹ thuật JavaScript tốt. Lập trường đầy quan điểm của ông về các yếu tố chính của ngôn ngữ đã gây ra nhiều cuộc thảo luận hữu ích. Điều đó nói rằng, có quá nhiều người coi mỗi lời tuyên bố "xấu" hoặc "có hại" là phúc âm, từ chối nhìn xa hơn ý kiến của một người. Nó có thể là một chút bực bội đôi khi.
Việc sử dụng chức năng được cung cấp bởi new
từ khóa có một số lợi thế so với việc xây dựng từng đối tượng từ đầu:
- Di truyền nguyên mẫu . Mặc dù thường được xem xét với sự pha trộn giữa sự nghi ngờ và dè bỉu của những người quen với các ngôn ngữ OO dựa trên lớp, kỹ thuật kế thừa tự nhiên của JavaScript là một phương tiện sử dụng lại mã đơn giản và hiệu quả đáng ngạc nhiên. Và từ khóa mới là phương tiện chính (và chỉ có sẵn trên nhiều nền tảng) có nghĩa là sử dụng nó.
- Hiệu suất. Đây là tác dụng phụ của # 1: nếu tôi muốn thêm 10 phương thức cho mọi đối tượng tôi tạo, tôi có thể viết một hàm tạo tự gán từng phương thức cho từng đối tượng mới ... Hoặc, tôi có thể gán chúng cho chức năng tạo
prototype
và sử dụng new
để dập tắt các đối tượng mới. Điều này không chỉ nhanh hơn (không cần mã cho mỗi và mọi phương thức trên nguyên mẫu), nó còn tránh việc tạo bóng cho từng đối tượng với các thuộc tính riêng cho từng phương thức. Trên các máy chậm hơn (hoặc đặc biệt là trình thông dịch JS chậm hơn) khi nhiều đối tượng đang được tạo, điều này có thể có nghĩa là tiết kiệm đáng kể thời gian và bộ nhớ.
Và vâng, new
có một nhược điểm rất quan trọng, được mô tả bằng các câu trả lời khác: nếu bạn quên sử dụng nó, mã của bạn sẽ bị hỏng mà không có cảnh báo. May mắn thay, nhược điểm đó dễ dàng được giảm thiểu - chỉ cần thêm một chút mã vào chính hàm:
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
Bây giờ bạn có thể có những lợi thế của new
mà không phải lo lắng về các vấn đề gây ra do vô tình sử dụng sai. Bạn thậm chí có thể thêm một xác nhận vào kiểm tra nếu suy nghĩ về mã bị hỏng âm thầm làm phiền bạn. Hoặc, như một số nhận xét, sử dụng kiểm tra để giới thiệu ngoại lệ thời gian chạy:
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Lưu ý rằng đoạn mã này có thể tránh mã hóa cứng tên hàm xây dựng, vì không giống như ví dụ trước, nó không cần phải thực sự khởi tạo đối tượng - do đó, nó có thể được sao chép vào từng hàm mục tiêu mà không cần sửa đổi.)
John Resig đi sâu vào chi tiết về kỹ thuật này trong bài đăng Khởi tạo "Lớp" đơn giản của mình , cũng như bao gồm một phương tiện xây dựng hành vi này vào "các lớp" của bạn theo mặc định. Chắc chắn đáng đọc ... như là cuốn sách sắp ra mắt, Bí mật của Ninja JavaScript , mà thấy ẩn vàng trong việc này và nhiều người khác "có hại" đặc trưng của ngôn ngữ JavaScript (các chương trên with
là đặc biệt soi sáng cho chúng ta những người ban đầu bị sa thải tính năng không phù hợp này như một mánh lới quảng cáo).