Not 100%. There are a small handful of really wicked gotchas. I think there’s a lot of articles on them. I can’t find the one I like and don’t want to share one I haven’t read yet.
In this first example, ASI inserts an undesired semicolon:
return
{a: 0}
This returns undefined, and doesn’t continue on to execute the block containing a statement 0 with label a. (Change it to {a: 0, b: 0} and you get a syntax error because of this reinterpretation of what was intended as an object literal.)
In this second example, ASI doesn’t insert a desired semicolon:
f()
[].forEach.call(…)
This becomes a syntax error, because the [] has become subscripting rather than an array literal. (Incidentally, [].forEach is smelly anyway; prefer Array.prototype.forEach, maybe assign that to a constant if you’re doing it much.)
The second example could be replaced with something more common like:
f()
['foo', 'bar'].forEach(...)
Which is probably a type error, except if `f()` returns something like:
function f() {
return {
bar: ['Not the array', 'you were expecting'],
}
}
Then you would actually iterate over the returned `bar` array, not the expected `['foo', 'bar']` array.
Another fairly likely example of a desired semicolon not inserted is when the following line starts with a template string literal:
f()
`This is tagged with whatever f() returns`
This will most likely be a type error, except if `f()` returns a function, that function will then be called on the template string to do whatever. However I have a hard time imagining when you would want to start a statement with a template string literal without doing something smelly like: