0

I have a module defaultSettingsDefs which defines and exports an object defaultSettings:

/* defaultSettingsDefs.js */

const defaultSettings = {
    theme: 'light',
}

export { defaultSettings }

And I have a class Settings (which handles app settings' changes) which is fed defaultSettings in the constructor like so:

/* index.js */

import { Settings } from './classes/Settings'

import { defaultSettings } from './defs/defaultSettingsDefs'

const settings = new Settings(defaultSettings)

Since defaultSettings is imported from defaultSettingsDefs also in many other places within the app, I tried to make it completely immutable in order to avoid accidental overwrites. So in order to take care of the properties I froze the object within the definition itself:

/* defaultSettingsDefs.js */

const defaultSettings = Object.freeze({
    theme: 'light',
})

export { defaultSettings }

which works fine and doesn't allow overwriting defaultSettings's properties neither from index.js nor, for example, from Settings itself;

Furthermore, overwriting defaultSettings itself (not its properties) from index.js correctly throws an error as expected and desired, since defaultSettings is a module import:

import { Settings } from './classes/Settings'

import { defaultSettings } from './defs/defaultSettingsDefs'

defaultSettings = 1

// throws "Uncaught TypeError: Cannot set property defaultSettings of #<Object> which has only a getter"

however, defaultSettings itself can still be overwritten, e.g., from Settings in the constructor:

/* Settings.js */

constructor(defaultSettings) {
    defaultSettings = 1
}

// doesn't throw any error and messes up my app

First off, I don't quite understand why this happens. Shouldn't defaultSettings's immutability persist when it's passed down to a class?

And secondly, how do I go about fixing this?

Thanks a lot!

kos
  • 510
  • 3
  • 18
  • 3
    `defaultSettings = 1` is not a mutation of `defaultSettings`, it is a **reassignment** of the local variable `defaultSettings` in the `constructor` function. – Mulan Jul 13 '22 at 20:50
  • @Mulan Yeah I think I'm getting confused here. I don't quite understand the difference between doing that within the class and doing that within `index.js` though. It would be great if you could shed some light... I'm learning javascript along with react, and I think I'm just confusing the use of references and values here. – kos Jul 13 '22 at 21:08
  • @kos It's different variables. Maybe it helps to use a different name and write `constructor(mySettings) { mySettings = 1; }` instead - calling `new Settings(defaultSettings)` will not try to assign `1` to the global `defaultSettings` variable. – Bergi Jul 13 '22 at 23:20
  • @kos hopefully [this illustration](https://i.imgur.com/T1UbhWW.png) helps. – Mulan Jul 13 '22 at 23:25
  • @Bergi This is what is still unclear to me, I guess I have some reading to do - I'm picturing this in the same way this would work in, say, C, where you would have a pointer passed around and where you'd dereference the pointer in order to change the value - I guess this is not what's happening here. Thank you for your input – kos Jul 14 '22 at 05:04
  • 1
    @Mulan It does, thanks, and as to how Javascript works in that regard - I guess I got the whole pass by value / reference wrong since the start. Thanks a lot for taking the time to draw an illustration for that, I appreciate it! – kos Jul 14 '22 at 05:08
  • 1
    @kos It's like `void* mySettings = defaultSettings` in C. You can do either `mySettings.theme = 'dark'` which parallels `mySettings->theme = 'dark'` (writing into the pointed-at memory), or `mySettings = 1` which parallels `mySettings = &(1)` (putting a different pointer in the local variable). – Bergi Jul 14 '22 at 07:32
  • @Bergi Got it, thanks a lot. I'm pretty sure the confusion stemmed from reading something like "arrays and object are not passed by value but a reference to them is passed instead", which I misinterpreted as "arrays and object are passed by reference". Which doesn't make too much sense thinking about it now... Thanks a lot for explaining with a direct reference to C! – kos Jul 14 '22 at 20:38

0 Answers0