The this.notes &&
ensures that this.notes
exists first. If it doesn't exist, it'll return without throwing an error (to be more precise, it'll return the falsey value of this.notes
- probably undefined
).
If you unconditionally returned this.notes.sort
, an error will be thrown if this.notes
is not an array. For example:
class Notes {
sortedNotes() {
return (
this.notes &&
this.notes.sort((a, b) => {
const aDate = new Date(a.createdAt)
const bDate = new Date(b.createdAt)
return bDate - aDate
})
)
}
}
const n = new Notes();
// this.notes doesn't exist yet, so this doesn't do anything, but at least it doesn't throw an error:
n.sortedNotes();
console.log('done');
class Notes {
sortedNotes() {
return (
this.notes.sort((a, b) => {
const aDate = new Date(a.createdAt)
const bDate = new Date(b.createdAt)
return bDate - aDate
})
)
}
}
const n = new Notes();
// Throws:
n.sortedNotes();
console.log('done');
So the test for this.notes
' existence is needed to avoid an error when this.notes
doesn't exist when sortedNotes
is called.
It may have just been a typo, but make sure that something follows the return
statement other than a plain newline - either use return this.notes.sort((a, b) => {
, or put an opening parentheses (
right after it, to avoid ASI problems. (otherwise, nothing will be returned)
return (foo && bar);
means: Evaluate foo
. If it is truthy, evaluate bar
and return bar
. Otherwise, return foo
.
return (bar && foo);
means: Evaluate bar
. If it is truthy, evaluate foo
and return foo
. Otherwise, return bar
.
In your context, a more accurate minimal example would be when it's not known whether a property exists yet. Eg
return obj.fn()
will throw if obj
is undefined, whereas
return obj && obj.fn();
will not throw.
All this said, this is odd code to write. It would be much more readable to have an explicit test instead, eg something like:
if (!obj) {
return 'Not defined yet!';
} else {
return obj.fn();
}