It seems that COALESCE may be expanded to a CASE/WHEN, which causes the expression to get evaluated twice (link); ISNULL apparently doesn't have this behavior. This has a performance impact (i.e. when ...
The value of check_expression is returned if it is not NULL; otherwise, replacement_value is returned after it is implicitly converted to the type of check_expression, if the types are different.
I've been in an argument with one of our devs that took an update statement with an inner join and made it a left join (because inner was missing some records somehow in the left table - tableB in ...