I find myself challenged to think of a reason, because it's almost never necessary and is more expensive. It does, however, change the context, so it is useful to know that this tool is in the box.
Consider the flows and the context.
Alice => this.something() => f()
msg.sender is Alice and
msg.value is whatever Alice sent.
Alice => this.something() => this.f()
msg.value is whatever
something() sent, which is probably 0.
The former is because
f() would be running in the context of Alice's message. The latter is because a new message was initiated from
this back to
this. Consequently, it has its own context.
Hope it helps.
Thanks, Steve Marx, for some ideas about why this might be useful in some cases. You can carve off a portion of the ether or the gas and you can also carry on if
f() fails, of you want to (not generally recommended). You would have to use
call() to invoke
this.f() to access such possibilities as
.gas(), like this: What does Solidity's "call" function mean?. It will return
(bool, bytes) where the bool is the success/failure of
f() and the outer function (
this) has a choice to continue or revert.