What you're seeing there is a peculiar result of how variable overloading works: When a variable (without "local" modifier) is overloaded, both the overloaded and the overloading definition refer to the same storage.
Immutable definitions, i.e. both functions(*) and constants, don't behave that way; they retain their original values (quite naturally, since they wouldn't be immutable otherwise).
This behavior of variable overloading is not self-evident. Long ago overloaded variables actually didn't share storage - each class got its own and the normal binding rules were applied to the identifier. Then the variable variety of your example would behave exactly as the constant case.
That was changed, if I recall correctly, mostly on pragmatic grounds: The only reason to overload a variable is either to modify its type or (more commonly) to override the initializer. In those cases, retaining the storage for the overloaded variable would just cause confusion (and hence bugs) and waste space in the objects.
Changing the type of an overloaded variable shouldn't really be allowed from a strict typing perspective either (the overloading type should only allowed to be more restrictive to work when the variable is queried, and may only be more lax when the variable is set).
So the overloading paradigm doesn't really work that well with variables in several perspectives. Strictly speaking it shouldn't be allowed, but it is useful to override initializers.
These problems does not apply to immutable defintions though, to which both constants and functions belong.
*) One can replace the constant x with a function returning the value in your example - the function behaves in the same way as the constant.