последовательность
При введении привязки данных и ответа в документации Vue особо отмечается, что ответ не может быть обновлен для объектов, которые передали метод Object.freeze(). Поэтому я намеренно проверил конкретное значение метода Object.freeze().
значение
Метод Object.freeze() используется для замораживания объекта, запрещая изменение свойств объекта (из-за数组本质也是对象, поэтому этот метод можно использовать с массивами). В Mozilla MDN это описано так:
Объект можно заморозить. Замороженный объект больше не может быть изменен; когда объект заморожен, к объекту нельзя добавить новые свойства, существующие свойства нельзя удалить, а перечисляемость, конфигурируемость и возможность записи существующих свойств объекта нельзя изменить. и не может изменить значение существующего свойства. Кроме того, после заморозки объекта прототип объекта не может быть изменен.
Возвращаемым значением этого метода является сам его параметр.
Следует отметить, что следующие два момента
-
Object.freeze() отличается от объявления константной переменной и не берет на себя функции константы.
const и Object.freeze() совершенно разные
- const ведет себя как let. Единственная разница между ними в том, что const определяет переменную, которую нельзя переназначить. Переменные, объявленные с помощью const, имеют область действия блока, а не области действия функции, как переменные, объявленные с помощью var.
- Const — это не то же самое, что Object.freeze(), const предотвращает перераспределение переменных, а Object.freeze() делает объекты неизменяемыми.
Следующий код правильный:
- Object.freeze() — это «неглубокая заморозка», допустим следующий код:
пример
нормальное использование
Очевидно, свойство prop не изменилось даже после переназначения.
продлевать
"Морозильник"
Чтобы полностью заморозить объекты с вложенными свойствами, вы можете написать свою собственную библиотеку или использовать существующую библиотеку для заморозки таких объектов, какDeepfreezeилиimmutable-js
// 深冻结函数.
function deepFreeze(obj) {
// 取回定义在obj上的属性名
var propNames = Object.getOwnPropertyNames(obj);
// 在冻结自身之前冻结属性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是个对象,冻结它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 冻结自身(no-op if already frozen)
return Object.freeze(obj);
}
На самом деле это простой рекурсивный метод. Но это требует очень важных знаний, которые редко используются при написании бизнес-логики.Object.getOwnPropertyNames(obj). Все мы знаем, что в JS Object есть свойства цепочки прототипов, и все свойства цепочки, не являющиеся прототипами, могут быть получены с помощью этого метода.
использоватьObject.freeze()Улучшить производительность
Помимо оптимизации компонентов, мы также можем начать с преобразования зависимостей vue. Во время инициализации Vue будет преобразовывать данные с помощью геттера и сеттера, В современных браузерах этот процесс на самом деле довольно быстрый, но все еще есть место для оптимизации.
Object.freeze()Вы можете заморозить объект.После заморозки вы не можете добавлять к объекту новые свойства, изменять значения его существующих свойств, удалять существующие свойства и изменять перечисляемость, конфигурируемость и конфигурируемость существующих свойств объекта. Этот метод возвращает замороженный объект.
Когда вы передаете простой объект JavaScript экземпляру Vuedataвариант, Vue будет перебирать все свойства этого объекта и использоватьObject.definePropertyПревратите все эти свойства в геттеры/сеттеры.Эти геттеры/сеттеры невидимы для пользователя, но внутренне они позволяют Vue отслеживать зависимости и уведомлять об изменениях при доступе к свойствам и их изменении.
Но Vue сталкивается с чем-то вродеObject.freeze()Если для этого параметра задано свойство объекта, которое нельзя настроить, методы перехвата данных, такие как setter getter, не будут добавлены к объекту.Обратитесь к исходному коду Vue.
Исходный код наблюдателя Vue
Сравнение эффекта повышения производительности
на основе Vuebig table benchmark, вы можете видеть, что при рендеринге таблицы 1000 x 10 включитеObject.freeze()Сравнение до и после повторного рендеринга.
big table benchmark
Перед включением оптимизации
После включения оптимизации
В этом примереиспользовалObject.freeze()в 4 раза быстрее, чем не использовать
ПочемуObject.freeze()производительность будет лучше
Не используйObject.freeze()Накладные расходы процессора
использоватьObject.freeze()Накладные расходы процессора
Из сравнения видно, что использованиеObject.freeze()После этого накладные расходы наблюдателя уменьшаются.
Object.freeze()Сценарии применения
так какObject.freeze()Это заморозит объект, поэтому он больше подходит для сцены класса отображения.Если ваши атрибуты данных нужно изменить, вы можете заменить его на новый.Object.freeze()Объект.
Размораживание объекта Javascript
Изменить реквизиты React Сгенерированные React объектные реквизиты не могут быть изменены, но необходимо изменить ситуацию, возникающую на практике реквизиты. Если они изменены напрямую, код ошибки js, поскольку объект реквизита заморожен, можно использовать Object.isFrozen(), в результате чего true Свойство Description объекта доступно только для чтения.
Ну, есть способы разморозить реквизит объекта, так изменить его?
На самом деле, в javascript после того, как объект заморожен, нет возможности разморозить его снова, только путем клонирования нового объекта с теми же свойствами и изменения свойств нового объекта для достижения цели.
Это можно сделать следующим образом:
ES6: Object.assign({}, frozenObject);
lodash: _.assign({}, frozenObject);
Давайте посмотрим на реальный код:
function modifyProps(component) {
let condictioin = this.props.condictioin,
newComponent = Object.assign({}, component),
newProps = Object.assign({}, component.props)
if (condictioin) {
if (condictioin.add) newProps.add = true
if (condictioin.del) newProps.del = true
}
newComponent.props = newProps
return newComponent
}
Как заблокировать объект
- Object.preventExtensions()
в проект нельзя добавлять новые свойства или методы Объекты не расширяемы, т.е. нельзя добавлять свойства или методы, но их можно изменять/удалять.
- Object.seal()
то же, что и предотвращение расширения, плюс предотвращает удаление существующих свойств и методов. На основании вышеизложенного свойства объекта не могут быть удалены, но могут быть изменены
- Object.freeze()
то же, что и уплотнение, плюс предотвращение изменения существующих свойств и методов На основании вышеизложенного все свойства объекта доступны только для чтения и не могут быть изменены
Вышеупомянутые три метода могут быть обнаружены Object.isExtensible(), Object.isSealed(), Object.isFrozen() соответственно.
Object.freeze() не позволяет Vue реализовать реактивную систему.
Когда создается экземпляр Vue, он добавляет все свойства, которые может найти в своем объекте данных, в систему реактивности Vue. Когда значение этих свойств изменяется, представление «отвечает», обновляя соответствие до нового значения. Но если используется Object.freeze(), это предотвращает изменение существующих свойств и означает, что система ответов больше не может отслеживать изменения.
Примеры конкретного использования:
<template>
<div>
<p>freeze后会改变吗
{{obj.foo}}
</p>
<!-- 两个都不能修改??为什么?第二个理论上应该是可以修改的-->
<button @click="change">点我确认</button>
</div>
</template>
<script>
var obj = {
foo: '不会变'
}
Object.freeze(obj)
export default {
name: 'index',
data () {
return {
obj: obj
}
},
methods: {
change () {
this.obj.foo = '改变'
}
}
}
</script>
После запуска:
Из ошибки видно, что свойство foo, доступное только для чтения, нельзя изменить. Object.freeze() замораживает значение. Вы все равно можете заменить ссылку на переменную. Измените приведенный выше код на:
<button @click="change">点我确认</button>
change () {
this.obj = {
foo: '会改变'
}
}
Object.freeze() — это новая функция в ES5. Она может заморозить объект. Замораживание означает, что вы не можете добавлять новые свойства к объекту, изменять значение его существующих свойств, удалять существующие свойства и изменять объект. и возможность записи существующих свойств. Предотвратить изменение объектов. Если у вас есть огромный массив или объект, и вы уверены, что данные не будут изменены, использование Object.freeze() может дать вам огромный прирост производительности.
Практические советы и рекомендации
Object.freeze() — это новая функция в ES5, которая может заморозить объект и предотвратить его изменение.
Vue 1.0.18+ поддерживает его.Для объектов, которые заморожены с помощью замораживания данных или vuex, vue не будет преобразовывать геттеры и сеттеры.
Если у вас есть огромный массив или объект, и вы уверены, что данные не будут изменены, использование Object.freeze() может дать вам огромный прирост производительности. В моей реальной разработке это улучшение примерно в 5-10 раз, и множитель увеличивается с объемом данных.
Кроме того, Object.freeze() замораживает значения, вы все равно можете заменить ссылки на переменные. Например:
<p v-for="item in list">{{ item.value }}</p>
new Vue({
data: {
// vue不会对list里的object做getter、setter绑定
list: Object.freeze([
{ value: 1 },
{ value: 2 }
])
},
created () {
// 界面不会有响应
this.list[0].value = 100;
// 下面两种做法,界面都会响应
this.list = [
{ value: 100 },
{ value: 200 }
];
this.list = Object.freeze([
{ value: 100 },
{ value: 200 }
]);
}
})
В документации Vue эта функция не описана, но это очень практичный подход.Для чистого отображения больших данных можно использовать Object.freeze для повышения производительности.