$target gets the target straight from the very specific raw message (like ":nick!address PRIVMSG #blah :blah blah"). I guess $chan, on the other side, is only really filled when you *join* a channel, then it's just referenced later. I believe that's why you should check if the server sends all the normal info again when you're forced to join the new channel.
I'm not sure, though. Just a guess.