There are actually two kinds of KDFs. One kind is designed to derive a key from high-entropy input (like another key); this can be done with a fast keyed hash like HMAC. The other kind takes a password as input. Passwords are low-entropy; they're not inherently very hard to brute-force. A good password hash thus has to be slow.
In your question, you said that adding for (i=0; i<bignum; i++);
would slow the hash. This is actually completely useless. The attacker does not have to play by your rules. Hashes need to protect passwords when the attackers have a copy of the hashes. If the attacker can compute hashes quickly, it doesn't matter how slowly you compute them. Hashes need to be inherently slow; there should be no shortcuts to evaluate them faster than the legitimate server.
The "randomness properties" are because a KDF needs to produce a key. They have nothing to do with precomputation, including rainbow tables. Cryptographic algorithms typically make certain assumptions about the key; among other things, they normally assume it was selected totally at random from the set of possible keys. Keys are also expected to be a certain length; their derivation functions need arbitrary-length output. In contrast, it's OK if a password hash has lots of structure to the output. Maybe there's a 70% chance that adjacent bits have the same value. Maybe it spreads 128 bits of entropy into 4096 bits of output. As long as it's hard to reverse, that's a fine hash, but it's unsuitable as a key.
A secure password-based key derivation function is a secure password hash (PBKDF2 is in fact one of the big 3 hashes). The reverse is not necessarily true. Which one to use is simple: use a password-based key derivation function to derive a key from a password, and a hash to store passwords.