2013-06-28 121 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)); 
    }; 
}()); 

但是現在你可以」您可以輕鬆地創建房產non-enumerablenon-configurablenon-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

我建議不要跟隨克羅克的單詞教學。

他的確有一些很好的建議,但值得一試。

例如,下劃線方面通常用於遵循更傳統的OOP編程風格的各種JS庫中。誠然,它並不是真正使私人的功能或價值,但它告訴任何用戶它應該被視爲 - 它不是公共接口的一部分 - 換句話說,該方法可能消失在下一個版本的圖書館。

即使JS實際上沒有常量,命名常量值的約定也是ALL_CAPS_WITH_UNDERSCORE。最後,許多JS開發者並不純粹是純JS,並且也與其他語言一起工作。像上述這樣的公約對於那樣的人來說應該是相當明顯的,最後最重要的是你的項目最實用的東西。