Skip to content Skip to sidebar Skip to footer

Assign New Property To Empty Object Which Has Frozen Prototype

Why can't I assign new properties to non-frozen object, which has frozen prototype: Working without Object.freeze: 'use strict' //This object will be prototype of next objects var

Solution 1:

What I don't get is why can't I assign to specificObject if its prototype is frozen?

Because property attributes are inherited. Yes, it's odd.

If you freeze an object, it will set the [[writable]] attribute of all data properties to false.

If you assign to an object property, but that property does not exist on the object, it will go and look it up on the prototype - it might be defined as setter there. When this lookup will return and say that there is a property of that name but it is non-writable, your assignment will fail (and throw in strict mode).

What can you do against this?

  • Use Object.defineProperty instead of assignment, it doesn't check the prototype
  • or similarly, use the second parameter of Object.create to create the own property
  • freeze the defaults only after you've assigned to specificObject.

Solution 2:

my understanding is that specificObject.sections is pointing to its' prototype which is defaults and it is frozen object. You define a new object {} but you try to assign it to defaults.sections. SpecificObject.sections is pointing exactly there.

If you create new ownProperty on specificObject it will work:

'use strict'//This object will be prototype of next objectsvar defaults = {
  name: 'def name',
  sections: {
    1: {
      secName: 'def sec name'
    }
  }
};

//!!!!!!!!!!!!Object.freeze(defaults);

//So we have an empty object with prototype set to our default object.var specificObject = Object.create(defaults);

// this will create new propertyObject.defineProperty(specificObject, 'sections',{
    enumerable: true,
    writable: true,
    configurable: true,
    value: {}
});
console.log(specificObject.hasOwnProperty('sections')); //true

specificObject.sections['1'] = Object.create(defaults.sections['1']);

explanation:

if you try to access obj.prop = val then javascript looks into obj's own properties, if not found then it looks into obj's prototype own properties. if found there then it /tries to assign val to/ lookup that property. if not found there then it tries to look into obj's prototype's prototype and so on. If prop is not found in the prototype tree then it creates new own property on obj and assigns val.

Therefore if prop is find on prototype and it is frozen you will get type error. Hope it brings some light.:)

EDIT:

as correctly pointed out by @KubaWyrostek specificObj.sections = {} will create new own property of specific Object, does not assign new value to the prototype's property, but it probably does the lookup for the property to check the writability, in that case it will run into frozen object. I didn't know about this before.

Post a Comment for "Assign New Property To Empty Object Which Has Frozen Prototype"