// suppose initially x == 0x123456 and x has type char *
x++
// x == 0x123457
this is really changing the value of a variable (neither of the pointers 0x123456 or 0x123457 have been changed in any way).Or if you say:
*x = 'a'
now you're modifying the memory at the address 0x123457 (again, the pointer itself has not changed).The fact that the pointer itself, as in the address to memory (as opposed to the variable holding that address or the contents of the memory being referred to) is immutable is of approximately no value to anyone.
And frankly, it makes no difference (for these examples) whether this is a language with pointers or references. You can still set variables holding references to new values (if the language allows mutable variables), and you can still mutate the memory that references address (if the language allows mutation of the objects referred to by references), and that's plenty of rope to hang yourself on even without being able to do pointer arithmetic on the address values.
The semantics of a programming language is what it is, not what you want it to be, unless you explicitly choose a language that allows you to express exactly what you mean.
The original statement was: "(I program in JavaScript where all values are immutable)" Its meaning depends on the semantics of 'values' and 'immutable'. If by 'values' you only mean primitive values (excluding objects and arrays) or by immutable you only mean immutable identity (excluding mutable state), you're comparing apples to oranges instead of Rust to JavaScript.
Immutable.js and PureScript exists for a reason: in JavaScript, not all values are immutable.
Object states are mutable, of course. But they are not values. You can't bind object states to variables. If you use objects as proxies for values that exist in your head but not in in JavaScript's semantics, that's fine, so long as you keep in mind the distinction between what you wish you were using and what you are actually using.