Difference between freeze and seal

JavascriptEcmascript 5

Javascript Problem Overview


I just heard about the JavaScript methods freeze and seal, which can be used to make any Object immutable.

Here's a short example how to use it:

var o1 = {}, o2 = {};
Object.freeze(o2);

o1["a"] = "worked";
o2["a"] = "worked";

alert(o1["a"]);   //prints "worked"
alert(o2["a"]);   //prints "undefined"

What is the difference between freeze and seal? Can they increase performance?

Javascript Solutions


Solution 1 - Javascript

Object.seal

  • It prevents adding and/or removing properties from the sealed object; using delete will return false
  • It makes every existing property non-configurable: they cannot be converted from 'data descriptors' to 'accessor descriptors' (and vice versa), and no attribute of accessor descriptors can be modified at all (whereas data descriptors can change their writable attribute, and their value attribute if writeable is true).
  • Can throw a TypeError when attempting to modify the value of the sealed object itself (most commonly in strict mode)

Object.freeze

  • Exactly what Object.seal does, plus:
  • It prevents modifying any existing properties

Neither one affects 'deep'/grandchildren objects. E.g., if obj is frozen, obj.el can’t be reassigned, but the value of obj.el could be modified, e.g. obj.el.id can be changed.


Performance:

Sealing or freezing an object may affect its enumeration speed, depending on the browser:

  • Firefox: enumeration performance is not impacted
  • IE: enumeration performance impact is negligible
  • Chrome: enumeration performance is faster with sealed or frozen objects
  • Safari: sealed or frozen objects enumerate 92% slower (as of 2014)

Tests: Sealed objects, Frozen objects.

Solution 2 - Javascript

I wrote a test project which compares these 3 methods:

  • Object.freeze()
  • Object.seal()
  • Object.preventExtensions()

My unit tests cover CRUD cases:

  • [C] add new property
  • [R] read existed property
  • [U] modify existed property
  • [D] remove existed property

Result:

enter image description here

Solution 3 - Javascript

You can always looks these up in MDN. In short:

  • Freeze: makes the object immutable, meaning no change to defined property allowed, unless they are objects.
  • Seal: prevent addition of properties, however defined properties still can be changed.

Solution 4 - Javascript

> Object.freeze() creates a frozen object, which means it takes an existing object and essentially calls Object.seal() on it, but it also marks all “data accessor” properties as writable:false, so that their values cannot be changed.

-- Kyle Simpson, You Don't Know JS - This & Object Prototypes

Solution 5 - Javascript

I have created a simple table to compare the below functions and explain the difference between these functions.

  • Object.freeze()
  • Object.seal()
  • Object.preventExtensions()

table that explains the difference between the above three methods

Solution 6 - Javascript

I was looking at the differences between Freeze and Seal in ECMAScript 5 and created a script to clarify the differences. Frozen creates an immutable object including data and structure. Seal prevents changes to the named interfaces - no adds, deletes - but you can mutate the object and redefine the meaning of its interface.

function run()
{
	var myObject = function() 
	{ 
		this.test = "testing"; 
	}
	
	//***************************SETUP****************************
	
	var frozenObj = new myObject();
	var sealedObj = new myObject();
	
	var allFrozen = Object.freeze(frozenObj);
	var allSealed = Object.seal(sealedObj);
	alert("frozenObj of myObject type now frozen - Property test= " + frozenObj.test);
	alert("sealedObj of myObject type now frozen - Property test= " + sealedObj.test);
	
	//***************************FROZEN****************************
	
	frozenObj.addedProperty = "added Property"; //ignores add
	alert("Frozen addedProperty= " + frozenObj.addedProperty);
	delete frozenObj.test; //ignores delete
	alert("Frozen so deleted property still exists= " + frozenObj.test);
	frozenObj.test = "Howdy"; //ignores update
	alert("Frozen ignores update to value= " + frozenObj.test);
	frozenObj.test = function() { return "function"; } //ignores
	alert("Frozen so ignores redefinition of value= " + frozenObj.test);
	
	alert("Is frozen " + Object.isFrozen(frozenObj));
	alert("Is sealed " + Object.isSealed(frozenObj));
	alert("Is extensible " + Object.isExtensible(frozenObj));
	
	alert("Cannot unfreeze");
	alert("result of freeze same as the original object: " + (frozenObj === allFrozen).toString());
	
	alert("Date.now = " + Date.now());
	
	//***************************SEALED****************************
	
	sealedObj.addedProperty = "added Property"; //ignores add
	alert("Sealed addedProperty= " + sealedObj.addedProperty);
	sealedObj.test = "Howdy"; //allows update
	alert("Sealed allows update to value unlike frozen= " + sealedObj.test);
	sealedObj.test = function() { return "function"; } //allows
	alert("Sealed allows redefinition of value unlike frozen= " + sealedObj.test);
	delete sealedObj.test; //ignores delete
	alert("Sealed so deleted property still exists= " + sealedObj.test);
	alert("Is frozen " + Object.isFrozen(sealedObj));
	alert("Is sealed " + Object.isSealed(sealedObj));
	alert("Is extensible " + Object.isExtensible(sealedObj));
	
	alert("Cannot unseal");
	alert("result of seal same as the original object: " + (sealedObj === allSealed).toString());
	
	alert("Date.now = " + Date.now());
}

Solution 7 - Javascript

I know I may be little late but

  • Similarity: both of them are used for creating non extensible objects.
  • Difference : In Freeze configurable , enumerable and writable attributes of the object are set to false. where as in Sealed writable attribute is set to true and rest of the attributes are false.

Solution 8 - Javascript

You can now force a single object property to be frozen instead of freezing the whole object. You can achieve this with Object.defineProperty with writable: false as a parameter.

var obj = {
    "first": 1,
    "second": 2,
    "third": 3
};
Object.defineProperty(obj, "first", {
    writable: false,
    value: 99
});

In this example, obj.first now has its value locked to 99.

Solution 9 - Javascript

I wrote about this in my open-source e-book. It has a section about object restrictions https://github.com/carltheperson/advanced-js-objects/blob/main/chapters/chapter-3.md#object-restrictions

To summarize:

This table shows the hierarchy of restrictions: Table of restrictions

Object.preventExtensions fail example

const obj = { a: "A", b: "B" }
Object.preventExtensions(obj)

obj.c = "C" // Failure

console.log(obj) // { a: "A", b: "B" }

Object.seal fail example

const obj = { a: "A", b: "B" }
Object.seal(obj)

delete obj.a // Failure
obj.c = "C" // Failure

console.log(obj) // { a: "A", b: "B" }

Object.freeze fail example

const obj = { a: "A", b: "B" }
Object.freeze(obj)

delete obj.a // Failure
obj.b = "B2" // Failure
obj.c = "C" // Failure

console.log(obj) // { a: "A", b: "B" }

Note: How they "fail" depends if your code is running in strict mode or not.

  • Strict mode = error

  • Not in strict mode = silent fail

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmajaView Question on Stackoverflow
Solution 1 - JavascriptNiccolò CampolungoView Answer on Stackoverflow
Solution 2 - JavascriptpiecioshkaView Answer on Stackoverflow
Solution 3 - JavascripttungdView Answer on Stackoverflow
Solution 4 - JavascriptshmuliView Answer on Stackoverflow
Solution 5 - JavascriptShwetabh ShekharView Answer on Stackoverflow
Solution 6 - JavascriptJayceeView Answer on Stackoverflow
Solution 7 - JavascriptFaisal NaseerView Answer on Stackoverflow
Solution 8 - JavascriptjaggedsoftView Answer on Stackoverflow
Solution 9 - JavascriptCarlThePersonView Answer on Stackoverflow