10

I am new to JavaScript. The following code is from some production codebase. The regDefinition is passed in JSON form. But I am not quite sure about the syntax in the method body. Especially the || and [] parts.

function getCookieValue(regDefinition) {
    return (document.cookie.match(regDefiniation.regEx) || [])[regDefiniation.index] || null;
}
1

5 Answers 5

31

It looks like someone has made a lot of effort to make this very hard to read.

If I interpret it right, it does something like this:

  • call the match method.
  • it returns an array of matches, or nothing (null, undefined?). If it doesn't return anything, default to an empty array.
  • Of the array, get the element with index 'regDefiniation.index'.
  • If that item doesn't exist (which can be the case for matches, and will always be the case for the empty default array), return null.
Sign up to request clarification or add additional context in comments.

6 Comments

+1 - So true. Other than a personal feeling of satisfaction for the first few minutes, writing code this way gives you or your end users nothing at all. Readability is king. By vote. And.. he could have spelt regDefiniation right!
This could also be code that has grown over time. Maybe the original coder thought that match would always return an array. Then the code failed, and someone hotfixed it by adding the || [] part. Whatever the reason, there is no shame in adding a line of comment, or even better, spend 3 or 5 lines of code instead of 1, so it is readable.
Many thanks. I always prefer readability. But sometimes, some people prefers to bet his fame on un-readability.
stuff() || default is an idiomatic expression in Javascript, and is not hard to read once one gets used to it. Some more whitespace would help, but I feel separating it into if and else statements would be overly verbose for most Javascript programmers.
@FengyangWang True, but combining a couple of such expressions makes it harder to read even if you know the syntax. If it were two lines like var matches = document....match(..) || []; return matches[index] || null; it would already be much more readable, while still having the same expressions without ifs and only two lines of code.
|
25

There are some good answers here, but nobody seems to really be explaining why you'd do

(foo || [])[bar]; // or similarly (foo || {})[bar]

instead of just

foo[bar]

Consider case the RegExp failed,

var foo = null, bar = 0;

Now without anything special you'd get an error thrown and the code would stop

foo[bar]; // TypeError: Cannot read property '0' of null

However the parenthesised-or version will be different

(foo || [])[bar]; // undefined (note, no error)

This is because the result of (null || []) is [], and you can now try to read a property of it safely

1 Comment

I think every answer mentions that || [] is there in case match doesn't return anything. Especially the (underappreciated) answer by @Wyzard makes this quite clear. But neither of us went in great detail about what kind of errors you would get, so kudos for that.
7

document.cookie is a string that contains the cookies associated with the current page. The document.cookie.match(regDefiniation.regEx) function call is searching this string with a regular expression to get a list of substrings that match.

If nothing in the cookie string matches the regex, the match call will return null, so the || [] is there to replace that null with an empty array. This ensures that the expression (document.cookie.match(regDefiniation.regEx) || []) always returns an array.

The [regDefiniation.index] is just retrieving an element from that array. But if the requested index doesn't exist in the array — for example, if the array is empty because the regex didn't match anything in the cookie string — the result will be undefined, so the || null changes the result to null in that case.

Comments

6

So to understand this let's dig into this example

var myValue = someValue || otherValue

So here if someValue can be converted into true then myValue would contain someValue else it would contain otherValue

// Values that evaluate to false:
false
"" // An empty string.
NaN // JavaScript's "not-a-number" variable.
null
undefined // Be careful -- undefined can be redefined!
0 // The number zero.

Anything else would return true

So to understand your code let's break it

var myCookie = document.cookie.match(regDefiniation.regEx) || []

So here if document.cookie.match(regDefiniation.regEx) returns true then return it else return the empty array. Same for other part too. For more information of logical operators in JavaScript please follow the following link

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

1 Comment

@AshishRajput I think it's more like an empty array than just object. Empty object is defined as {} in JavaScript.
3

Here's the step-by-step:

document.cookie returns a string and match method (inbuilt) is applied to that. If the parameter is in regDefiniation.regEx found, then do this else return [] (i.e., array) After this, whatever is returned by above step, apply indexing to that with [regDefiniation.index].

`If all the above steps fail, then return null.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.