Search code examples
javascriptnode.jsstreamlogical-operators

Not understanding logical operators in a specific situation


I was looking into another person's code and found this specific part where I don't understand what the logic operators are being used for. (Mind that I'm still starting out with JavaScript, but also did as much research as I could before coming for your aid.)

const createStream = (options) => {
  const stream = new PassThrough({
    highWaterMark: options && options.highWaterMark || null,
  });
  stream.destroy = () => { stream._isDestroyed = true; };
  return stream;
}; 

So, as far as I understand, this is a function createStream(options), basically, and it creates a variable called stream, which is a stream.PassThrough object.

Now, the part that bugs me a bit is the highWaterMark: options && options.highWaterMark || null, part. I simply don't understand any of this. I know how to use logical operators in if() statements for instance, but this just doesn't make sense to me, and I couldn't find a lot online to explain me this.

Appreciate any help I can get.


Solution

  • Both && and || have the same operator precedence and operate left-to-right. So

    highWaterMark: options && options.highWaterMark || null,
    

    is equivalent to

    highWaterMark: (options && options.highWaterMark) || null,
    

    Additionally, keep in mind that && resolves to the left side if the left side is falsy, otherwise it resolves to the right side. So if options is undefined, (options && options.highWaterMark) resolves to undefined.

    The && is needed there because if the options parameter doesn't exist (eg undefined or null), simply doing

    highWaterMark: options.highWaterMark || null,
    

    would throw an error, because you can't access properties of undefined or null.

    Then, for the || part: it will resolve to the left side if the left side is truthy, else it'll resolve to the right side. So there are two possible paths:

    // options starts out undefined
      highWaterMark: options && options.highWaterMark || null,
    // equivalent to
      highWaterMark: (options && options.highWaterMark) || null,
      highWaterMark: (undefined && options.highWaterMark) || null,
      highWaterMark: undefined || null,
      highWaterMark: null,
    

    Or:

    // options starts out as an object
      highWaterMark: options && options.highWaterMark || null,
    // equivalent to
      highWaterMark: (options && options.highWaterMark) || null,
      highWaterMark: (options.highWaterMark) || null,
      highWaterMark: options.highWaterMark,
    

    So, what the code does is it

    • checks to see if the options variable is truthy

    • If so, it assigns the highWaterMark property of options to the highWaterMark property of the object

    • Otherwise, it assigns null to that property

    It's equivalent to the following:

    let highWaterMark;
    if (options) {
      highWaterMark = options.highWaterMark;
    } else {
      highWaterMark = null;
    }
    const stream = new PassThrough({ highWaterMark });
    

    This allows callers of createStream to be either of the type:

    createStream();
    

    or

    createStream({ highWaterMark: 'foo' });