4
\$\begingroup\$

I have a particular if statement that could be written in different ways, and I'm curious as to whether there's any significant difference in readability that I should prefer one over the other:

The flow can be boiled down to

if string does not begin with '_'
    do stuff
else
    throw error

Some different ways of writing the if condition:

str[0] !== '_'
str.indexOf('_')
!/^_/.test(str)
/^[^_]/.test(str)
\$\endgroup\$
4
  • 1
    \$\begingroup\$ @palacsint, The title is the question, please don't change my question. \$\endgroup\$
    – zzzzBov
    Commented Jun 7, 2012 at 15:54
  • 2
    \$\begingroup\$ You title is suboptimal. It should really relate to the actual piece of code, its to generic right now. \$\endgroup\$ Commented Jun 8, 2012 at 17:53
  • 1
    \$\begingroup\$ What if the string is empty? \$\endgroup\$ Commented Jun 8, 2012 at 17:54
  • \$\begingroup\$ empty string is a valid condition, just not strings beginning with _. \$\endgroup\$
    – zzzzBov
    Commented Jun 8, 2012 at 18:11

4 Answers 4

12
\$\begingroup\$

I think the first is the simplest and the most readable one from the list but I'd prefer the charAt function:

x.charAt(0) !== '_'

Furthermore, I'd reverse the condition:

if string begins with '_' {
    throw error
}
do stuff

Reference:

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I'm guessing this is why you said you prefer it, but you should mention that charAt has greater compatibility than 'string'[0]. \$\endgroup\$
    – delete me
    Commented Jun 8, 2012 at 9:58
  • \$\begingroup\$ @st-boost: Actually not, I haven't known that. It was just more readable for me. Thanks for pointing that out! \$\endgroup\$
    – palacsint
    Commented Jun 8, 2012 at 11:21
3
\$\begingroup\$

If JavaScript provided a startsWith function I’d say that this would easily be the clearest since it expresses the intent exactly.

Of course you could add this method to the string class but that’s probably just overkill.

Of the methods you have shown, the one expressing the intent most directly is the third, namely using regular expressions and the start-of-string anchor: !/^_/.test(str).

Of course, this requires the reader to be passably fluent in regular expressions but this is a reasonable assumption. And not only that, it’s actually kind of a requirement when working on JavaScript code.

That said, you’re only testing for a single character here, so just testing that character directly makes a lot of sense, never mind that it’s way more efficient than a full-blown regular expression.

So in this particular case I’d compare the character directly; in the general case, the regular expression expresses the intent most clearly.

\$\endgroup\$
5
  • \$\begingroup\$ this requires the reader to be passably fluent in regular expressions but this is a reasonable assumption. I disagree. \$\endgroup\$
    – ANeves
    Commented Jun 8, 2012 at 10:02
  • 1
    \$\begingroup\$ @ANeves Then you are wrong, sorry. It’s as simple as that. Regular expressions are a fundamental part of the JavaScript language (and many other modern languages) and if you can’t read it you are simply impaired in those languages. It’s like saying that you can’t read for statements, only while. \$\endgroup\$ Commented Jun 8, 2012 at 10:19
  • \$\begingroup\$ Agreed: reg.ex. are a fundamental part of JS and we are impaired if we can't read them. Disagreed: "reasonable assumption". One can make a living from JS without being "passably fluent" in regex, without knowing the difference between === and ==, etc. I think it's risky to assume that these impaired developers do not exist. \$\endgroup\$
    – ANeves
    Commented Jun 8, 2012 at 12:35
  • 2
    \$\begingroup\$ @ANeves Let me rephrase them: you should not write code aimed to ease understanding for such people. Because the direct consequence of this is that you restrict yourself unreasonably and consequently write worse code. Write idiomatic code, not idiotic code. \$\endgroup\$ Commented Jun 8, 2012 at 13:11
  • 1
    \$\begingroup\$ One can make a living from JS without understanding what foo = foo || {} means, doesn't mean I shouldn't use it. I wholeheartedly agree about assuming that other developers would understand regular expressions (or at least assume that they'd be smart enough to look up what it does). JS even has RegExp literals which IMHO changes them from being an advanced feature to a fundamental part of the language. \$\endgroup\$
    – zzzzBov
    Commented Jun 8, 2012 at 13:17
2
\$\begingroup\$

The first one is the most clear, to me. You're only testing one character so the patterns in the 3rd and 4th are a little overkill. The second one is OK, but still not as clear as the first.

\$\endgroup\$
2
\$\begingroup\$

Go with the option that makes the code clearest. Unless you're optimizing for performance (after you have profiled your code to ensure this is the bottleneck, of course), there is no need to consider performance for a trivial case like this.

Of these options:

str[0] !== '_'
str.indexOf('_')
!/^_/.test(str)
/^[^_]/.test(str)

The latter two require you understand some regex, which is not at all simple, intuitive, readable, or natural for humans. The second one requires the reader to manually convert an integer to a boolean. The first one clearly identifies the purpose of the if-statement.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Just because you're not familiar with regex doesn't mean nobody is. It's not the right solution for this problem, but there are plenty of problems for which the simplest, most intuitive, and most readable solution is a regex. \$\endgroup\$
    – delete me
    Commented Jun 8, 2012 at 9:54
  • \$\begingroup\$ @st-boost My point is merely that for such a simple problem a regex is complete overkill. I'm very familiar with regex, and when I am skimming through code I can't just glance at a simple regex and immediately comprehend. It takes a second to recognize it. I'll agree that regex are best for some problems, but often they are not. They are useful for keeping parsing separate from logic, but keep in mind: >> Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. \$\endgroup\$ Commented Jun 8, 2012 at 13:11
  • \$\begingroup\$ Well I agree that it's overkill here, and that it's easy to use regular expressions when there is a better alternative. But I do think that, in some situations, I (and the average reader) can decipher a regex faster than we could process an equivalent body of code. \$\endgroup\$
    – delete me
    Commented Jun 8, 2012 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.