2013-06-28 11 views
15

Byłem dobrym programistą JavaScript i stosowałem się do coding conventions zarejestrowanym przez Douglas Crockford. Jednak od tego czasu JavaScript ewoluował i uważam, że konwencje nazewnictwa są już nieaktualne.Definiowanie właściwości i konwencji nazewnictwa w JavaScript

Na przykład Crockforda powiedział:

Nie używaj _ (podkreślenia) jako pierwszego znaku nazwy. Czasami jest używany do wskazania prywatności, ale w rzeczywistości nie zapewnia prywatności. Jeśli prywatność jest ważna, skorzystaj z formularzy zapewniających private members. Unikaj konwencji, które wykazują brak kompetencji.

Jednak JavaScript pozwala teraz tworzyć właściwości nieprzeliczalne. Dlatego też ma sens (przynajmniej dla mnie - możesz się nie zgodzić) na prefiks nieprzeliczalny właściwości z podbarwnym, aby wskazać, że właściwość jest nieprzeliczalna.

Dlaczego miałbyś to zrobić?

  1. Ponieważ visual feedback is important (przewiń w dół do sekcji czytelności w połączonym artykule).
  2. Kompatybilność wstecz. Możesz odfiltrować właściwości zaczynające się od podbarwników w pętlach for in.

Weźmy inny przykład co Crockforda powiedział:

Zmienne globalne powinny być we wszystkich czapki. (JavaScript nie ma makr ani stałych, więc nie ma sensu używać wszystkich wielkich liter do oznaczenia funkcji, których JavaScript nie posiada).

Jak widzę, występują dwa problemy z następującą konwencją:

  1. Większość programistów JavaScript nie zapisuje zmiennych globalnych we wszystkich limitach. To po prostu nie jest naturalne.
  2. JavaScript pozwala teraz tworzyć właściwości, których nie można zapisywać. Dlatego też sensowne jest używanie wszystkich kapsli dla takich właściwości z tych samych powodów, które wskazałem powyżej dla właściwości nieprzeliczalnych.

Wszystko to dobrze i dobrze, ale co to jest prawdziwe pytanie pytasz? Spójrz na funkcję Object.defineProperties. Problem polega na tym, że musisz podać deskryptor właściwości dla każdej właściwości, którą chcesz zdefiniować. To jest zbyt szczegółowe. Na przykład:

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; 
     } 
    } 
}); 

Zamiast byłoby znacznie lepiej, gdyby można było po prostu zrobić:

var o = {}, x = 0; 

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

Funkcja define byłoby zdefiniowane następująco:

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)); 
    }; 
}()); 

Jednak teraz można” t łatwo utworzyć własność non-enumerable, non-configurable lub non-writable.Stąd ja zmodyfikowano funkcję define następująco:

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); 
      } 
     } 
    }; 
}()); 

Teraz właściwości rozpoczynające się znak podkreślenia są dla przeliczalny, właściwości zakończonej Underbar są dla konfigurowalne i danych Właściwości deskryptora, które nie mają żadnych małe alfabety są dla -pisuje.

Moje pytanie brzmi następująco: czy istnieje sposób na łatwe uzyskanie właściwości nieprzeliczalnych, niekonfigurowalnych lub nie zapisywalnych przy jednoczesnym przestrzeganiu konwencji nazewniczych Crockford? Wiem, że moje własne konwencje nazewnictwa mają więcej zalet. Jednak nie chcę zbyt szybko opuszczać konwencji Crockforda.

+0

Jest to podobne do: http://stackoverflow.com/questions/4484424/underscore-prefix-for-property-and-method-names-in-javascript –

Odpowiedz

14

Proponuję nie stosować się do słowa nauczającego Crocka.

Ma kilka dobrych rad, ale warto wziąć to z przymrużeniem oka.

Na przykład aspekt podkreślenia jest powszechnie stosowany w różnych bibliotekach JS, które mają bardziej klasyczny styl programowania OOP. To prawda, że ​​nie czyni funkcji lub wartości naprawdę prywatnymi, ale mówi każdemu użytkownikowi, że powinno być traktowane jako takie - że nie jest częścią publicznego interfejsu - innymi słowy, metoda może zniknąć w następnej wersji biblioteka.

Konwencja nazewnictwa wartości stałych jest również ALL_CAPS_WITH_UNDERSCORE, mimo że JS w rzeczywistości nie ma stałych.

W końcu wielu programistów JS nie jest wyłącznie JS-only i pracuje również z innymi językami. Konwencje takie jak powyższe powinny być raczej oczywiste dla takich osób, a najważniejsze jest to, co jest najbardziej praktyczne dla twojego projektu.