The second argument to a ko.computed sets the value of this when the function to determine the computed's value (the first arg) is executed. In the fullName case, the function uses this.firstName and this.lastName. So, whenever it is called we want to make sure that this is indeed our viewmodel.
In the second case, a variable called self was created that points to the appropriate value of this. Then, self is used inside the computed's function rather than using this (which is dynamic). In the second case, self could have been put as the second argument and then this could have been used inside the function.
This is really a matter of style. In my opinion, the use of a variable like self has fallen out of style these days. In the end, it comes down to personal preference.
Here is another answer that discusses this in KO as well: Difference between knockout View Models declared as object literals vs functions
Good tutorial on this in JavaScript here: https://derickbailey.com/email-courses/masteringthis/