Разница между замораживанием и печатью в Javascript
Я только что услышал о методах JavaScript freeze
и seal
, которые могут быть использованы для того, чтобы сделать любой объект неизменным.
Вот краткий пример того, как его использовать:
var o1 = {}, o2 = {};
Object.freeze(o2);
o1["a"] = "worked";
o2["a"] = "worked";
alert(o1["a"]); //prints "worked"
alert(o2["a"]); //prints "undefined"
В чем разница между этими методами и может ли они повысить производительность?
Ответы
Ответ 1
Object.seal
- Это предотвращает добавление и/или удаление свойств из запечатанного объекта; использование
delete
вернет false - Это делает каждое существующее свойство неконфигурируемым: они не могут быть преобразованы из "дескрипторов данных" в "дескрипторы доступа" (и наоборот), и никакой атрибут дескрипторов доступа не может быть изменен вообще (тогда как дескрипторы данных могут изменить свой атрибут
writable
, и их value
атрибута, если writeable
true). - Может
TypeError
при попытке изменить значение самого запечатанного объекта (чаще всего в строгом режиме)
Object.freeze
- Именно то, что делает
Object.seal
, плюс: - Это предотвращает изменение любых существующих свойств
Ни один из них не влияет на "глубокие"/внуковые объекты. Например, если obj
заморожен, obj.el
может быть переназначен, но значение obj.el
может быть изменено, например, obj.el.id
может быть изменено.
Спектакль:
Запечатывание или замораживание объекта может повлиять на скорость его перечисления, в зависимости от браузера:
- Firefox: на производительность перечисления это не влияет
- IE: влияние на производительность перечисления незначительно
- Хром: производительность перечисления быстрее с запечатанными или замороженными объектами
- Safari: закрытые или замороженные объекты подсчитывают на 92% медленнее (по состоянию на 2014 год)
Тесты: Запечатанные объекты, Замороженные объекты.
Ответ 2
Вы всегда можете посмотреть их в MDN. Короче говоря:
- Freeze: делает объект неизменным, что означает, что никакое изменение в разрешенное свойство не допускается, если только они не являются объектами.
- Seal: предотвратить добавление свойств, однако определенные свойства по-прежнему могут быть изменены.
Ответ 3
Я написал проект , который сравнивает эти 3 метода:
-
Object.freeze()
-
Object.seal()
-
Object.preventExtensions()
Мои модульные тесты охватывают случаи CRUD:
- [C] добавить новое свойство
- [R] читать существующее свойство
- [U] изменить существующее свойство
- [D] удалить существующее свойство
Результат:
![enter image description here]()
Ответ 4
Object.freeze()
создает замороженный объект, что означает, что он принимает
существующий объект и по существу вызывает на нем Object.seal()
, но он также
маркирует все свойства "data accessor" как writable:false
, так что их
значения не могут быть изменены. - Кайл Симпсон, вы не знаете JS - это и прототипы объектов
Ответ 5
Я рассматривал различия между Freeze и Seal в ECMAScript 5 и создал script, чтобы прояснить различия. Frozen создает неизменяемый объект, включая данные и структуру. Печать предотвращает изменения названных интерфейсов - не добавляет, не удаляет - но вы можете мутировать объект и переопределять смысл его интерфейса.
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());
}
Ответ 6
Я знаю, что может быть немного поздно, но
- Сходство: оба из них используются для создания не расширяемых
объекты.
- Разница: во Freeze настраивается, перечислима и доступна для записи
атрибуты объекта установлены на
false
. где, как и в Sealed
записываемый атрибут имеет значение true
, а остальные атрибуты - false.
Ответ 7
Теперь вы можете принудительно заморозить одно свойство объекта, а не замораживать весь объект. Вы можете достичь этого с помощью Object.defineProperty
с writable: false
в качестве параметра.
var obj = {
"first": 1,
"second": 2,
"third": 3
};
Object.defineProperty(obj, "first", {
writable: false,
value: 99
});
В этом примере obj.first
теперь имеет значение, заблокированное до 99.