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.
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' });