2013-06-28 3 views
15

Я был хорошим программистом JavaScript и придерживался coding conventions, зачисленный Douglas Crockford. Однако JavaScript с тех пор развивается, и я считаю, что соглашения об именах устарели.Определение свойств и соглашений об именах в JavaScript

Например Крокфорд сказал:

Не используйте _ (подчеркивание) в качестве первого символа имени. Иногда это используется для указания конфиденциальности, но на самом деле это не обеспечивает конфиденциальность. Если конфиденциальность важна, используйте формы, которые предоставляют private members. Избегайте соглашений, которые демонстрируют недостаточную компетентность.

Однако JavaScript теперь позволяет создавать неперечислимые свойства. Следовательно, имеет смысл (по крайней мере, мне - вам разрешено не согласиться) префикс неперечислимых свойств с нижним баром, чтобы указать, что свойство не перечислимо.

Зачем вам это делать?

  1. visual feedback is important (прокрутите вниз до раздела читаемости в связанной статье).
  2. Обратная совместимость. Вы можете отфильтровать свойства, которые начинаются с нижнего бара в петлях for in.

Давайте возьмем другой пример того, что сказал Крокфорд:

Глобальные переменные должны быть заглавными буквами. (JavaScript не имеет макросов или констант, поэтому нет смысла использовать все кепки для обозначения функций, которые не имеют JavaScript.)

Как я вижу, есть две проблемы со следующим соглашением:

  1. Большинство программистов из JavaScript не записывают глобальные переменные во всех кепках. Это просто неестественно.
  2. Теперь JavaScript позволяет создавать свойства, недоступные для записи. Следовательно, имеет смысл использовать все шапки для таких свойств по тем же причинам, что и выше, для неперечислимых свойств.

Все это хорошо и прекрасно, но что это на самом деле вопрос, спросите вы? Посмотрите на функцию Object.defineProperties. Проблема в том, что вам нужно предоставить дескриптор свойства для каждого свойства, которое вы хотите определить. Это слишком многословно. Например:

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

Вместо этого, было бы гораздо лучше, если вы могли бы просто сделать:

var o = {}, x = 0; 

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

define функция будет определяться следующим образом:

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

Однако теперь вы можете» t сделать недвижимость non-enumerable, non-configurable или non-writable легко.Поэтому я изменил функцию define следующим образом:

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

Теперь свойство, начинающееся с подчеркиванием не является перечислимо, свойством, заканчивающееся с подчеркиванием не являются конфигурируемыми и данными свойств дескрипторов, которые не имеют какой-либо строчные являются не -writable.

Итак, мой вопрос заключается в следующем: существует ли способ сделать объекты неперечислимыми, неконфигурируемыми или непригодными для записи, все еще придерживаясь соглашений об именовании Crockford? Я знаю, что мои собственные соглашения об именах имеют больше преимуществ. Однако я не хочу слишком быстро отказаться от конвенций Крокфорда.

+0

Это похоже на: http://stackoverflow.com/questions/4484424/underscore-prefix-for-property-and-method-names-in-javascript –

ответ

14

Я предлагаю не следовать инструкциям Крокса дословно.

У него есть хороший совет, но стоит взять его с солью.

Например, подчеркивающий аспект обычно используется в различных библиотеках JS, которые следуют более классическому стилю программирования ООП. Верно, что это не делает функцию или значение правдиво частной, но она говорит любым пользователям, что она должна рассматриваться как таковая, - что она не является частью открытого интерфейса - другими словами, метод может исчезнуть в следующей версии библиотека.

Соглашение об именовании константоподобных значений также равно ALL_CAPS_WITH_UNDERSCORE, хотя у JS фактически не было констант.

В конце концов, многие разработчики JS не просто JS-only и работают с другими языками. Упомянутые выше конвенции должны быть достаточно очевидны для таких людей, и в конечном итоге важно то, что наиболее практично для вашего проекта.