I've been a good JavaScript programmer and adhered to the coding conventions enlisted by Douglas Crockford. However JavaScript has evolved since then and I believe the naming conventions are now outdated.
For example Crockford said:
Do not use
_
(underbar) as the first character of a name. It is sometimes used to indicate privacy, but it does not actually provide privacy. If privacy is important, use the forms that provide private members. Avoid conventions that demonstrate a lack of competence.
However JavaScript now allows you to create non-enumerable properties. Hence it makes sense (at least to me - you're allowed to disagree) to prefix non-enumerable properties with an underbar to indicate that the property is non-enumerable.
Why should you do so?
for in
loops.Let's take another example of what Crockford said:
Global variables should be in all caps. (JavaScript does not have macros or constants, so there isn't much point in using all caps to signify features that JavaScript doesn't have.)
As I see it there are two problems with the following convention:
All that's well and fine, but what's the real question you ask? Look at the Object.defineProperties
function. The problem is that you need to supply a property descriptor for each property you want to define. This is too verbose. For instance:
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;
}
}
});
Instead it would be much better if you could simply do:
var o = {}, x = 0;
define(o, {
E: Math.E,
get x() {
return x;
},
set x(y) {
x = y;
}
});
The define
function would be defined as follows:
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));
};
}());
However now you can't make a property non-enumerable
, non-configurable
or non-writable
easily. Hence I modified the define
function as follows:
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);
}
}
};
}());
Now properties beginning with an underbar are non-enumerable, properties ending with an underbar are non-configurable and data descriptor properties which don't have any lowercase alphabets are non-writable.
So my question is this - is there any way to make properties non-enumerable, non-configurable or non-writable easily while still adhering to Crockford's naming conventions? I know that my own naming conventions have more merits. However I don't want to abandon Crockford's conventions too hastily.
Naming ConventionsVariable and function names written as camelCase. Global variables written in UPPERCASE (We don't, but it's quite common) Constants (like PI) written in UPPERCASE.
What Does Naming Convention Mean? Naming conventions are general rules applied when creating text scripts for software programming. They have many different purposes, such as adding clarity and uniformity to scripts, readability for third-party applications, and functionality in certain languages and applications.
A JavaScript function is defined with the function keyword, followed by a name, followed by parentheses (). Function names can contain letters, digits, underscores, and dollar signs (same rules as variables). The parentheses may include parameter names separated by commas: (parameter1, parameter2, ...)
I would suggest not following Crock's teaching word for word.
He does have some good advice, but it's worth taking it with a grain of salt.
For example, the underscore aspect is commonly used in various JS libraries which follow a more classical OOP style of programming. It is true it does not make a function or value truely private, but it tells any users it should be treated as such - that it's not a part of the public interface - in other words, the method could disappear in the next version of the library.
The convention for naming constant-like values is also ALL_CAPS_WITH_UNDERSCORE
even though JS didn't actually have constants.
In the end, many JS devs are not purely JS-only and work with other languages too. Conventions like the above should be rather obvious for people like that, and what matters in the end is what's most practical for your project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With