2013-06-28 51 views
15

Tôi đã là một lập trình viên JavaScript tốt và tôn trọng coding conventions được đăng ký theo số Douglas Crockford. Tuy nhiên, JavaScript đã phát triển kể từ đó và tôi tin rằng các quy ước đặt tên hiện đã lỗi thời.Xác định các thuộc tính và quy ước đặt tên trong JavaScript

Ví dụ Crockford nói:

Không sử dụng _ (dưới) là ký tự đầu tiên của một tên. Nó đôi khi được sử dụng để chỉ ra sự riêng tư, nhưng nó không thực sự cung cấp sự riêng tư. Nếu quyền riêng tư là quan trọng, hãy sử dụng các biểu mẫu cung cấp private members. Tránh các quy ước thể hiện sự thiếu năng lực.

Tuy nhiên, JavaScript hiện cho phép bạn tạo thuộc tính không thể đếm được. Do đó nó có ý nghĩa (ít nhất là với tôi - bạn được phép không đồng ý) để tiền tố bất động sản tiền tố với một thanh dưới để chỉ ra rằng tài sản là không liệt kê.

Tại sao bạn nên làm như vậy?

  1. visual feedback is important (cuộn xuống phần có thể đọc trong bài viết được liên kết).
  2. Khả năng tương thích ngược. Bạn có thể lọc ra các thuộc tính bắt đầu bằng một thanh dưới trong các vòng for in.

Chúng ta hãy một ví dụ về những gì Crockford nói:

biến toàn cầu nên trong tất cả các mũ. (JavaScript không có macro hoặc hằng số, do đó không có nhiều điểm trong việc sử dụng tất cả các mũ để biểu thị các tính năng mà JavaScript không có.)

Như tôi thấy có hai vấn đề với quy ước sau đây:

  1. Hầu hết các lập trình viên JavaScript không viết các biến toàn cầu trong tất cả các mũ. Nó không phải là tự nhiên.
  2. JavaScript giờ đây cho phép bạn tạo các thuộc tính không thể ghi. Do đó nó có ý nghĩa để sử dụng tất cả các mũ cho các thuộc tính như vậy cho những lý do tương tự như tôi đã nêu ở trên cho các thuộc tính không thể đếm được.

Tất cả điều đó tốt và tốt, nhưng câu hỏi thực sự bạn yêu cầu là gì? Nhìn vào hàm Object.defineProperties. Vấn đề là bạn cần cung cấp một bộ mô tả đặc tính cho mỗi thuộc tính mà bạn muốn định nghĩa. Điều này quá dài dòng. Ví dụ:

var o = {}, x = 0; 

Object.defineProperties(o, { 
    E: { 
     value: Math.E, 
     enumerable: true, 
     configurable: true 
    } 
    x: { 
     enumerable: true, 
     configurable: true, 
     get: function() { 
      return x; 
     }, 
     set: function (y) { 
      x = y; 
     } 
    } 
}); 

Thay vào đó, sẽ tốt hơn nhiều nếu bạn chỉ đơn giản có thể làm:

var o = {}, x = 0; 

define(o, { 
    E: Math.E, 
    get x() { 
     return x; 
    }, 
    set x(y) { 
     x = y; 
    } 
}); 

Chức năng define sẽ được xác định như sau:

var define = (function() { 
    var defineProperty = Object.defineProperty; 
    var has = Function.call.bind(Object.hasOwnProperty); 
    var getDescriptorOf = Object.getOwnPropertyDescriptor; 

    return function (obj, props) { 
     for (var key in props) 
      if (has(props, key)) 
       defineProperty(obj, key, 
        getDescriptorOf(props, key)); 
    }; 
}()); 

Tuy nhiên bây giờ bạn có thể' Tạo một thuộc tính non-enumerable, non-configurable hoặc non-writable dễ dàng.Do đó tôi sửa đổi define chức năng như sau:

var define = (function() { 
    var defineProperty = Object.defineProperty; 
    var has = Function.call.bind(Object.hasOwnProperty); 
    var getDescriptorOf = Object.getOwnPropertyDescriptor; 

    return function (obj, props) { 
     for (var key in props) { 
      if (has(props, key)) { 
       var descriptor = getDescriptorOf(props, key); 

       if (key.charAt(0) === "_") 
        descriptor.enumerable = false; 

       if (key.charAt(key.length - 1) === "_") 
        descriptor.configurable = false; 

       if (has(descriptor, "value") && key === key.toUpperCase()) 
        descriptor.writable = false; 

       defineProperty(obj, key, descriptor); 
      } 
     } 
    }; 
}()); 

Bây giờ tính bắt đầu với một thanh dưới đều là phòng không đếm được, tài sản kết thúc với một thanh dưới là tài sản mô tả không thể cấu hình và dữ liệu mà không có bất kỳ bảng chữ cái chữ viết thường không - có thể ghi. Vì vậy, câu hỏi của tôi là điều này - có cách nào để làm cho các thuộc tính không được liệt kê, không thể cấu hình hoặc không thể ghi dễ dàng trong khi vẫn tuân thủ các quy ước đặt tên của Crockford không? Không. Tôi biết rằng các quy ước đặt tên của riêng tôi có nhiều thành tích hơn. Tuy nhiên tôi không muốn từ bỏ các quy ước của Crockford quá vội vàng.

+0

Điều này tương tự như: http://stackoverflow.com/questions/4484424/underscore-prefix-for-property-and-method-names-in-javascript –

Trả lời

14

Tôi khuyên bạn không nên tuân theo lời dạy của Crock.

Anh ấy có một số lời khuyên tốt, nhưng đáng để lấy nó bằng một hạt muối.

Ví dụ: khía cạnh gạch dưới thường được sử dụng trong các thư viện JS khác nhau theo một phong cách lập trình OOP cổ điển hơn. Đúng là nó không làm cho một hàm hay giá trị thực sự riêng tư, nhưng nó cho bất kỳ người dùng nào nó phải được xử lý như vậy - rằng nó không phải là một phần của giao diện công cộng - nói cách khác, phương pháp có thể biến mất trong phiên bản tiếp theo của thư viện.

Quy ước đặt tên các giá trị giống nhau cũng là ALL_CAPS_WITH_UNDERSCORE mặc dù JS không thực sự có hằng số.

Cuối cùng, nhiều nhà phát triển JS không hoàn toàn là JS và chỉ làm việc với các ngôn ngữ khác. Các quy ước như trên nên khá rõ ràng đối với những người như vậy, và những gì quan trọng cuối cùng là những gì thực tế nhất cho dự án của bạn.

Các vấn đề liên quan