This question already has answers here:
Why can I change a constant object in javascript
(12 answers)
Closed 1 year ago.
I have been working on some exercise with let and const and found something interesting with const along with objects assignments.
As per definition: In JavaScript, const means that the identifier can’t be reassigned.
const numConst = 20;
numConst = 40;
console.log("numConst", numConst);
Uncaught TypeError: Assignment to constant variable.
Whereas when I try to modify the object declared with const, it is allowed:
const person = { name: "test", age: 20 };
person.age = 40;
console.log("person.age", person.age); // outputs: person.age 40
Why does const behave differently with object?
https://www.w3schools.com/JS/js_const.asp
The keyword const is a little misleading.
It does NOT define a constant value. It defines a constant reference to a value.
Because of this, we cannot change constant primitive values, but we can change the properties of constant objects.
const a = {foo: 'bar'}; defines a new object (thus a new reference). this reference will be stored in a.
when invoking a = {bar: 'foo'} later, you tell the program, to change the reference a. This is not allowed due to the const constraint.
On the other hand, a.bar = 'foo' will modify the value refenreced by a, but not the reference itself.
You assign an object to const which is reference type. Now if you add new keys to object or modifiy the existing values of key you can do so because person preserving the reference of that object and by using person.age you are changing the value of object not the reference.
But if you try to assign a new reference to person like this
const person = { name: 'test', age: 20 };
person = { name: 'hi', age: 10 };
console.log(person);
you will get error Uncaught TypeError: Assignment to constant variable.
Both arrays and objects are reference type and by using same reference you can add or remove keys from object or can change values. Same as using arrays you can push new values or can pop but can't assign a new reference to that const.
const behave differently for object because when you create something like:
const person = {name:"test",age:20};
here person holds the reference (memory address) in it and when you change some data in object its reference is not changed but the key:value pair is changed that's the reason it doesn't show error in case of objects.
Related
Is it possible in JavaScript to reassign const variable;
In C++ we can cast variable to and from const, but is it something similar possible in JavaScript;
Here I ask about
const a = 1;
unconst(a);
a = "xyz";
a === "xyz" // true
Not object properties reassignments and array push/pop;
or
let a = 1;
const(a);
a = "xyz"; // error
a === 1 // true
a is const now, something like Object.freeze for objects
No, not with standard API. See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
Constants are block-scoped, much like variables defined using the let statement. The value of a constant can't be changed through reassignment, and it can't be redeclared.
The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered.
This question already has answers here:
When to use const with objects in JavaScript?
(6 answers)
Closed 5 years ago.
my question is simple about Const. i have seen a lot places that devs prefer const over let and var while declaring object even its properties are mutable. Could somebody explain this?
const a = {};
a.name = "";
console.log(a.name);
Simply to prevent the object itself being overwritten or having its type changed. The constant will always be an object.
const a = {};
a = 'foo';
const b = {};
b = { foo: 'bar' };
Both will throw:
Uncaught TypeError: Assignment to constant variable.
It prevents a (in your example) from being assigned a different reference, but properties within the object are often needed to be changed as they convey the current state of the object instance.
A simply analogy, which is more correct here?
var me = "Scott";
const me = "Scott";
What should happen if this then happens?
me = you;
Let's forget the fact that, in real life, you can change you name if you really want to. In this case me should always and forever reference, well, me - "Scott" so const is the better declaration.
But, over my lifetime, characteristics of me will change, some that are out of my control and some that are in my control. So, while we don't want the me reference to change to reference a different object, aspects of the object that me does reference should be able to be changed:
const me = {};
me.height = "6' 1"; // Used to be 6' 3" back in the day!
But, if you needed a constant value to hold in an object, you could declare a private variable in a constructor function to do that.
function Me(height){
// Some aspects of this object will never change. They can be set up
// as private data:
const bloodType = "B+";
// Others are just properties:
this.height = height;
}
Or, you could continue to use an object literal, but you'd need to "lock down" certain properties so that become read-only. This is done with Object.defineProperty.
According to MDN
The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its parameters) can be altered.
This question already has answers here:
What is the preferred declaration convention for objects or arrays: const or let?
(4 answers)
Closed 5 years ago.
This might be a silly question, but I wanted to see if there were any best practices in terms of what to assign to a CONST or LET variable. I understand CONST variables cannot be reassigned once declared, but I noticed that by assigning an object to a CONST variable, you can update the contents of the object.
const person = {
name: "John"
}
console.log(person.name) => //"John"
person.name = "Kim"
console.log(person.name) => //"Kim"
Would this be considered bad practice? If not, why not use LET variable?
Your example isn't bad practice, and is perfectly acceptable because person still refers to the same object, even though you've changed a property. You could add, remove or change properties and person still refers to your object.
ES6 const makes the binding immutable, not the value.
In ES6 you should use const if you don't need to rebind, otherwise use let. In your example you are not rebinding person so it is valid and correct.
If for example you had a second object person2 and tried to rebind like person = person2 then that would throw a type error.
If you wish to make your object value immutable, you can do that with Object.freeze() like so:
const person = Object.freeze({
name: "John"
});
person.name = "Kim";
// quietly fails or throws a type error
If i am not wrong, the pointer that the variable name is using cannot change in memory, but the thing the variable points to might change.
let name = "google";
const foo = name;
console.log(foo); //prints google
name = "yahoo";
console.log(foo); //prints google again instead of yahoo
Should it not print yahoo, as the variable name's value has been changed.. Can anyone explain me this.
Another example, where its changes...
const foo = [];
foo.push("test");
console.log(foo); // outputs ["test"]
I am getting confused here, can anyone explain me this.
Your first example uses an immutable string and the second uses a mutable object.
JS strings are immutable after being declared or created, so foo is not a reference to name's value, it points to the string. You're not changing the strings, you're pointing to a different one.
The array variable points to the object and continues pointing to the same object after it's been mutated. You're still pointing to the same object, however, since const is not deep.
This also highlights a common misunderstanding with JS' const, which functions more like Java's final than C++'s const. You are declaring a variable as const, not an instance of the object, so it only prevents you from reassigning to the variable, it does not prevent you from mutating the underlying object.
From MDN:
The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned.
This means that you can change the value assigned to a const, say by changing array or object, but cannot assign a new value to the const variable. E.g.:
Valid:
const a = [];
a.push(5);
console.log(a);
const b = {};
b['foo'] = 'bar';
console.log(b);
Invalid: This will throw error
const a = [];
a = [5];
console.log(a);
const b = {};
b = {'foo': 'bar'};
console.log(b);
I'm having some troubles to understand what is copied and what is referenced in javascript. What is clear to me is that an object is referenced when it's an object and copied when it's a variable:
var reference = myObject // myObject = {string:'text'} -> referenced
var copy = myVar // myVar = 'text' -> copied
Now what if I want to create an object of objects/var?
var newObject = {anObject: myObject, aVar: myVar}
Will they be copied or referenced? If they are copied, is there a way to make them referenced (at least the object: myObject)?
Edit (Angularjs specific): I wanted to make sure that everything answered is also true with AngularJS and the $rootScope variables (even though I guess the behavior should be identical)
Objects are Passed by Reference In JavaScript
object references are
values. Because of this, objects will behave like they are passed by
reference: If a function changes an object property, it changes the
original value. Changes to object properties are visible (reflected)
outside the function.
if you assign an object to property of another object it is still assigned by reference. while you change the new object value it reflect in base.
eg:
var myObj = {
a: 1
}
var testObj = {
ref: myObj
}
console.log(myObj.a); //1
//change the value from second object
testObj.ref.a = "new val";
console.log(myObj.a); //new val
Primitive values are copied and Non primitive values such as objects and arrays are referenced.
I think "myObject" will be referenced and myVar will be copied. To get the copy of myObject, you can clone it and assign it to the other variable.
Using JQuery:
{
anObject: $.extend({},myObject),
aVar: myVar
}