There are two issues here. One is whether the input gets coerced from Date to numeric. The other is whether the output gets coerced to numeric.
Input
For loops coerce Date inputs to numeric, because as @DWin and @JoshuaUlrich point out, for loops take vectors, and Dates are technically not vectors.
> for(d in dates) print(class(d))
[1] "numeric"
[1] "numeric"
On the other hand, lapply and its simplifier offspring sapply have no such restrictions.
> sapply( dates, function(day) class(day) )
[1] "Date" "Date"
Output
However! The output of class() above is a character. If you try actually returning a date object, sapply is not what you want.
lapply does not coerce to a vector, but sapply does:
> lapply( dates, identity )
[[1]]
[1] "2013-01-01"
[[2]]
[1] "2013-01-02"
> sapply( dates, identity )
[1] 15706 15707
That's because sapply's simplification function coerces output to a vector.
Summary
So: If you have a Date object and want to return a non-Date object, you can use lapply or sapply. If you have a non-Date object, and want to return a Date object, you can use a for loop or lapply. If you have a Date object and want to return a Date object, use lapply.
Resources for learning more
If you want to dig deeper into vectors, you can start with John Cook's notes, continue with the R Inferno, and continue with SDA.