parseInt works correctly, please look at the docs.
String representations starting with "0" are considered octal numbers. So
parseInt('09') starts parsing '09' as octal and stops when if encounters an invalid character ('9' in this case) so you get 0 as result.
Always use the second parameter (radix) with parseInt:
parseInt('09', 10); // returns 9
Browsers like Chrome seem to always assume 10 as default value of the second parameter but you must not rely on that.
Btw, another simple way of converting String to Number is the following:
'09'*1; // 9
It will even work with floats:
'3.14'*1; // 3.14
If you only want integer part, you can use a bitwise operator:
'3.14'|0; // 3
No quirks that I know of...