Immutable values in javascript - javascript

I'm currently in the learning process of JavaScript and really get confused about immutable values. What I understand is, when a value is created (stings/numbers/booleans), it can never be changed.
Now my question is, the variable that I assign values, the value of that variable is changeable. I can assign new values to that variable. So why immutability is important?
Also, when I assign a new value to a variable, what happen to the previous value? Does it stay in memory and block some spaces? Does it lost its pointer from that variable? Actually what happen?
Please help me to understand what is the actual use of the concepts "Mutable" and "Immutable" in JavaScript. Thanks in advance.

What You Seem Confused About
Assignment of a variable has nothing to do with immutable or mutable objects. A variable is simply an alias: it refers to an object in memory. When you change a variable's value, all you've done is tell the compiler to stop associating that object with this variable and associate it with another object instead. Assignment does not affect the underlying object - the object never changes, you just no longer have a way to access it anymore.
Usually, when all references to an object are lost, they are garbage collected i.e. the memory allocated for the object is released and the object is lost forever. However, this also has nothing to do with the difference between immutable and mutable objects.
The Real Difference Between Immutable and Mutable Objects
Immutable objects do not modify the object in place (i.e change what it looks like) - they return a new copy of the data with the variables changed.
Mutable objects in Javascript do not return a copy, but let you change the object itself.
I liken it to the difference between array.splice() and array.slice(). splice() will change the original array by removing/inserting elements where needed - slice() will create a new array with just the elements you want. They can be made to do the same things - but one mutates the array in place, the other one creates a copy.
An immutable object is forced to always return a new copy when changed - it will not by itself be changed. A mutable object can - but does not have to - be mutated in place. Primitive types in Javascript are mostly immutable - you cannot change the form of a string once created (if you call replace on the JS string, you will receive a new string with the values you asked for replaced, not the same string with the value changed). Objects are mostly mutable: for instance you can do object[key] = value and change the object everywhere it is referenced.
tl;dr
When you change a mutable object, it is changed everywhere it is referenced. When you change an immutable object, it isn't changed at all - a new object is created, and all the old references to the object will give you the original object with nothing different about it.

Related

In what way are datatypes immutable? [duplicate]

If a string is immutable, does that mean that....
(let's assume JavaScript)
var str = 'foo';
alert(str.substr(1)); // oo
alert(str); // foo
Does it mean, when calling methods on a string, it will return the modified string, but it won't change the initial string?
If the string was mutable, does that mean the 2nd alert() would return oo as well?
It means that once you instantiate the object, you can't change its properties. In your first alert you aren't changing foo. You're creating a new string. This is why in your second alert it will show "foo" instead of oo.
Does it mean, when calling methods on
a string, it will return the modified
string, but it won't change the
initial string?
Yes. Nothing can change the string once it is created. Now this doesn't mean that you can't assign a new string object to the str variable. You just can't change the current object that str references.
If the string was mutable, does that
mean the 2nd alert() would return oo
as well?
Technically, no, because the substring method returns a new string. Making an object mutable, wouldn't change the method. Making it mutable means that technically, you could make it so that substring would change the original string instead of creating a new one.
On a lower level, immutability means that the memory the string is stored in will not be modified. Once you create a string "foo", some memory is allocated to store the value "foo". This memory will not be altered. If you modify the string with, say, substr(1), a new string is created and a different part of memory is allocated which will store "oo". Now you have two strings in memory, "foo" and "oo". Even if you're not going to use "foo" anymore, it'll stick around until it's garbage collected.
One reason why string operations are comparatively expensive.
Immutable means that which cannot be changed or modified.
So when you assign a value to a string, this value is created from scratch as opposed to being replaced. So everytime a new value is assigned to the same string, a copy is created. So in reality, you are never changing the original value.
I'm not certain about JavaScript, but in Java, strings take an additional step to immutability, with the "String Constant Pool". Strings can be constructed with string literals ("foo") or with a String class constructor. Strings constructed with string literals are a part of the String Constant Pool, and the same string literal will always be the same memory address from the pool.
Example:
String lit1 = "foo";
String lit2 = "foo";
String cons = new String("foo");
System.out.println(lit1 == lit2); // true
System.out.println(lit1 == cons); // false
System.out.println(lit1.equals(cons)); // true
In the above, both lit1 and lit2 are constructed using the same string literal, so they're pointing at the same memory address; lit1 == lit2 results in true, because they are exactly the same object.
However, cons is constructed using the class constructor. Although the parameter is the same string constant, the constructor allocates new memory for cons, meaning cons is not the same object as lit1 and lit2, despite containing the same data.
Of course, since the three strings all contain the same character data, using the equals method will return true.
(Both types of string construction are immutable, of course)
The text-book definition of mutability is liable or subject to change or alteration.
In programming, we use the word to mean objects whose state is allowed to change over time. An immutable value is the exact opposite – after it has been created, it can never change.
If this seems strange, allow me to remind you that many of the values we use all the time are in fact immutable.
var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);
I think no one will be surprised to learn that the second line in no way changes the string in statement.
In fact, no string methods change the string they operate on, they all return new strings. The reason is that strings are immutable – they cannot change, we can only ever make new strings.
Strings are not the only immutable values built into JavaScript. Numbers are immutable too. Can you even imagine an environment where evaluating the expression 2 + 3 changes the meaning of the number 2? It sounds absurd, yet we do this with our objects and arrays all the time.
Immutable means the value can not be changed. Once created a string object can not be modified as its immutable. If you request a substring of a string a new String with the requested part is created.
Using StringBuffer while manipulating Strings instead makes the operation more efficient as StringBuffer stores the string in a character array with variables to hold the capacity of the character array and the length of the array(String in a char array form)
From strings to stacks... a simple to understand example taken from Eric Lippert's blog:
Path Finding Using A* in C# 3.0, Part Two...
A mutable stack like System.Collections.Generic.Stack
is clearly not suitable. We want to be
able to take an existing path and
create new paths from it for all of
the neighbours of its last element,
but pushing a new node onto the
standard stack modifies the stack.
We’d have to make copies of the stack
before pushing it, which is silly
because then we’d be duplicating all
of its contents unnecessarily.
Immutable stacks do not have this problem. Pushing onto an immutable
stack merely creates a brand-new stack
which links to the old one as its
tail. Since the stack is immutable,
there is no danger of some other code
coming along and messing with the tail
contents. You can keep on using the
old stack to your heart’s content.
To go deep on understaning immutability, read Eric's posts starting with this one:
Immutability in C# Part One: Kinds of Immutability
One way to get a grasp of this concept is to look at how javascript treats all objects, which is by reference. Meaning that all objects are mutable after being instantiated, this means that you can add an object with new methods and properties. This matters because if you want an object to be immutable the object can not change after being instantiated.
Try This :
let string = "name";
string[0] = "N";
console.log(string); // name not Name
string = "Name";
console.log(string); // Name
So what that means is that string is immutable but not constant, in simple words re-assignment can take place but can not mutate some part.
The text-book definition of mutability is liable or subject to change or alteration. In programming, we use the word to mean objects whose state is allowed to change over time. An immutable value is the exact opposite – after it has been created, it can never change.
If this seems strange, allow me to remind you that many of the values we use all the time are in fact immutable.
var statement = "I am an immutable value"; var otherStr = statement.slice(8, 17);
I think no one will be surprised to learn that the second line in no way changes the string in statement. In fact, no string methods change the string they operate on, they all return new strings. The reason is that strings are immutable – they cannot change, we can only ever make new strings.
Strings are not the only immutable values built into JavaScript. Numbers are immutable too. Can you even imagine an environment where evaluating the expression 2 + 3 changes the meaning of the number 2? It sounds absurd, yet we do this with our objects and arrays all the time.

Are all variables in js converted to objects before being executed?

From what I have understood, primitive data types such as a string can also have properties ie string can have .includes . Does that mean all primitive data types are converted to objects before being executed. If yes, what is the point of having distinct difference between primitive data types and objects.
Whenever you try to refer to a property of a string s, JavaScript converts the string value to an object as if by calling new String(s). This object inherits string methods and is used to resolve the property reference. Once the property has been resolved, the newly created object is discarded.
Numbers and booleans have methods for the same reason that strings do: a temporary object is created using the Number() or Boolean() constructor, and the method is resolved using that temporary object.
source Javascript: The Definitive Guide. David Flanagan
When you call a property on a string (lower case) primitive, the JS runtime creates a new instance of a String (upper case) object and copies the string primitive value into the new "wrapper" object, then the property or method that you originally called gets called on the wrapper object and then that wrapper object is garbage collected when the statement is completed. This makes it only seem like some primitives have properties when they actually don't.
If yes, what is the point of having distinct difference between
primitive data types and objects.
The point is that primitives are lightweight entities that have a low memory footprint, whereas Objects can do more and therefore require a larger memory footprint. Also, you can't inherit from a primitive, whereas you can from an Object.
If you'll only be doing limited Object operations, using a primitive is the best approach, but if you know that you'll be using many properties of an Object, it's more efficient to create the Object using a constructor from the start to avoid the constant creation and destruction of wrapper objects.

Assigning new property to object using deconstruction

I am reviewing a PR and i found the follwing choice for assigning a new property to an object.
foo = {
...foo,
bar: "value"
};
And im wondering if there is any advantage of doing that instead of just going for
foo.bar= "value";
Thanks!
Yes, there is. By doing it the way you showed, you will be creating a brand new object in memory, rather than mutating the existing one. In other words, this is an immutable operation.
The usual reason for doing immutable operations is that it enables faster equality checking, because it is just a single reference check, as opposed to having to deeply compare all the properties of the objects.

Get a direct reference to a JavaScript property

After answering this question about using the style.top property of a div in jQuery's $.animate(), I started to wonder if there was a way to do it more in line with what the OP had thought (s)he could do.
The question is: can we get a direct reference to an object's property when that property is a primitive type?
For example, if you had an object called myDiv, you could get a reference to its style property, because that's an object, but is there any way to get a reference to the top property of style so that when this changes, you don't have to retrieve it again and again? (Note: I'm not saying this retrieval is computationally significant. This is just a question about what's possible, not what's good practice.)
var myDiv = document.getElementById('myDiv');
myDiv.style.top = "100px";
var myDivStyle = myDiv.style;
var myDivStyleTop = myDiv.style.top;
myDiv.style.top = "200px";
console.log(myDivStyle.top); // will print "200px"
console.log(myDivStyleTop); // will obviously print "100px"
Is there a way to reference that top property directly without going through style? My instinct is no, but JS has surprised me before, so I just wanted to make sure.
No. A variable are just simple container that can hold a value. Assigning a new value to a variable can never change the value of another variable or property.
In this regard, it doesn't matter whether the variable holds a primitive values or an object, that's just how variables work.
No there isn't. Primitives are immutable and never stored by reference.
From MDN
object reference
A link to an object. Object references can be used as if they were the objects they link to. The concept of object references arises when assigning the same object to more than one property. Each assigned property does not hold a copy of the object. Instead, they hold object references that link to the same object. In practice, this means that if the object is modified, all properties referring to the object reflect the modification.
primitive, primitive value
A data that is not an object and does not have any methods. JavaScript has 5 primitive datatypes: string, number, boolean, null, undefined. With the exception of null and undefined, all primitives values have object equivalents which wrap around the primitive values, e.g. a String object wraps around a string primitive. All primitives are immutable.

Memory Usage/Garbage Collection of Objects Passed Into Functions

When an object is passed into a function, the object is passed by value (although the value for an object is a reference). I am passing very large objects into my functions, but only accessing a handful of properties (6-12) from within the function. Memorywise, would it be better to only pass the properties instead of the whole object? Or would this actually create more of a memory issue if my properties are strings?
Given the two functions below, what happens memorywise? In f1, does javascript/v8 create a new object foo in memory or is it really just a pointer? Does it remain just a pointer if I access a string property or does V8 then make a copy of that string for use within the function. In f2, I assume that a completely new copy of the string foo is made for the function. Is this a correct assumption?
function f1(x) {
var y = x.foo;
}
function f2(foo) {
var y = foo;
}
var obj = {foo: "test"};
f1(obj);
f2(obj.foo);
"Memorywise, would it be better to only pass the properties instead of the whole object? Or would this actually create more of a memory issue if my properties are strings? "
That would require more memory. Doesn't really matter if they're strings, since strings are generally implemented as Reference Types as well, but for each argument, there will be a copy of the value instead of just a single copy of the Object reference.
The object reference is very light weight, so you just as just copy that instead of all individual members of the object.
Also, this will be required if you rely on mutations of the object within the function.
In your examples, there's only one property being passed (a string). If your code doesn't rely on mutations of the object itself, then there'll be no significant difference between the two.
In the example that passes the object, the only copy is the object reference. It isn't a pointer, but it is very light weight, and nothing to be concerned about.
In the example that passes the string, it would seem as though it makes a copy of the entire string, but since stings are immutable in JavaScript, implementations generally implement them as reference types as well.
Therefore it's as efficient to pass a single character string as it is to pass a 10,000 character string.

Categories

Resources