This would be O(n) in time, since you do a constant number of operations on each node. Conceptually, there isn't a more efficient way of doing things (in terms of big-O notation, there's some code optimization that could be done.)
The reason why you can't exceed O(n) is because, in order to do so, you would need to skip some nodes. Since you need to modify each node, this wouldn't be possible.
Efficiency then comes down to a constant factor. The fewer operations you can do per item in the list, the faster your code will execute.
I'd implement like this:
function reverseLinkedList(list, previous){
//We need to use the the current setting of
//list.next before we change it. We could save it in a temp variable,
//or, we could call reverseLinkedList recursively
if(list.next !== null){
reverseLinkedList(list.next, list);
}
//Everything after 'list' is now reversed, so we don't need list.next anymore.
//We passed previous in as an argument, so we can go ahead and set next to that.
list.next = previous;
}
reverseLinkedList(list, null);
Of course, this is recursive, so it would be inefficient in terms of space, but I like recursive code :)
This also doesn't return the reversed linked list, but we could fairly easily modify things to do so if that were important.