What's the benefit of Object.freeze() not freezing objects within the passed object?

匿名 (未验证) 提交于 2019-12-03 01:20:02

问题:

I was learning more about the methods of JavaScript's Object constructor on MDN and I noticed that the last sentence of Object.freeze's description reads:

Note that values that are objects can still be modified, unless they are also frozen.

A behavior like that seems like it should be opt-in. What exactly is the benefit of having to manually freeze a frozen object's objects recursively?

If I'm freezing an object, why would I want the objects inside of it to still be mutable?

回答1:

The answer lies in the point itself

Note that values that are objects can still be modified, unless they are also frozen. 

Update:

There is no official information any where regarding the design decision of freeze() method

I think, basically for performance reasons they have took this decision, if we have wanted to make the internal objects also freezed, we would have to apply the method recursively. So this is a big overhead, so the design decision was made to avoid this.

If it was not the performance, the method would have behaved differently.



回答2:

I think if recursive is the default strategy, some complex Objects could not behave as expected. Think about following situation:

<div id="root">     <div id="stem">         <div id="leaf>         </div>     </div> </div> 

and for some reason I want to freeze the stem, so I wrote these code:

Object.freeze(document.getElementById('stem')); 

If it freezes recursively, the leaf would be frozen too, and it seems OK: if I want to freeze the stem, I also want to freeze it's children.

But wait, note that stem has another property -- It has parentElement too. So what will happen? When I freeze stem, I also freeze stem.parentElement, and stem.parentElement.parentElement... This is never what I want.



回答3:

After thinking about it more, it's probably to prevent the freezing of referenced objects that are also being referenced elsewhere (thus disabling another section of code that uses the same object). My response to that would be:

I wasn't suggesting it work that way. Object.freeze() would make more sense if the state of the object is captured completely. The references (to the objects) themselves could be immutable, but the object referenced would not be frozen.

If I did this...

var friend = {     name: 'Alec',     likes: {         programming: true,         reading: true,         cooking: false     } };  // Pass as frozen object doStuff(Object.freeze(friend));  document.addEventListener('click', function () {     friend.likes.clicking = true; }); 

...it would make sense that I don't want name to be changed AND I don't want the friend's likes to be changed by doStuff(). But I would still want to be able to change likes (just like I could change name) from an event listener, for example, without doStuff()'s object reference to friend changing too.

Edit: After reading Shaik's answer, I understand why they do it the way they do. Now, in order to have the functionality I would need in this example, I would do this:

function deepFreeze (obj) {     if (typeof obj !== 'object') return console.error('An object must be passed to deepFreeze()');     for (var key in obj) {         var val = obj[key];         if (typeof val === 'object') deepFreeze(val);     }     return Object.freeze(obj); } 

Are there any inherent problems with this?



回答4:

It all depends on the situation. You may want to freeze an object to prevent a new property set from being added, or being remove, however you may want existing properties to be altered. If you don't, just freeze them! IIRC, you can only freeze the parent object. Child objects would need a recursive freeze as well.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!