Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

语法:

Object.freeze(obj)  

// obj 参数 要被冻结的对象。

返回值:被冻结的对象

被冻结对象自身的所有属性都不可能以任何方式被修改。任何修改尝试都会失败,无论是静默地还是通过抛出TypeError异常(最常见但不仅限于strict mode)。

数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。数组作为一种对象,被冻结,其元素不能被修改。没有数组元素可以被添加或移除。

这个方法返回传递的对象,而不是创建一个被冻结的副本。

冻结对象

var obj = {prop: function() {},foo: 'bar'
};// 新的属性会被添加, 已存在的属性可能
// 会被修改或移除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;// 作为参数传递的对象与返回的对象都被冻结
// 所以不必保存返回的对象(因为两个对象全等)
var o = Object.freeze(obj);o === obj; // true
Object.isFrozen(obj); // === true// 现在任何改变都会失效
obj.foo = 'quux'; // 静默地不做任何事
// 静默地不添加此属性
obj.quaxxor = 'the friendly duck';// 在严格模式,如此行为将抛出 TypeErrors
function fail(){'use strict';obj.foo = 'sparky'; // throws a TypeErrordelete obj.quaxxor; // 返回true,因为quaxxor属性从来未被添加obj.sparky = 'arf'; // throws a TypeError
}fail();// 试图通过 Object.defineProperty 更改属性
// 下面两个语句都会抛出 TypeError.
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });// 也不能更改原型
// 下面两个语句都会抛出 TypeError.
Object.setPrototypeOf(obj, { x: 20 })
obj.__proto__ = { x: 20 }

冻结数组

let a = [0];
Object.freeze(a); // 现在数组不能被修改了.a[0]=1; // fails silently
a.push(2); // fails silently// In strict mode such attempts will throw TypeErrors
function fail() {"use strict"a[0] = 1;a.push(2);
}fail();

被冻结的对象是不可变的。但也不总是这样。下例展示了冻结对象不是常量对象(浅冻结)。

obj1 = {internal: {}
};Object.freeze(obj1);
obj1.internal.a = 'aValue';obj1.internal.a // 'aValue'

对于一个常量对象,整个引用图(直接和间接引用其他对象)只能引用不可变的冻结对象。冻结的对象被认为是不可变的,因为整个对象中的整个对象状态(对其他对象的值和引用)是固定的。注意,字符串,数字和布尔总是不可变的,而函数和数组是对象。

要使对象不可变,需要递归冻结每个类型为对象的属性(深冻结)。当你知道对象在引用图中不包含任何 环 (循环引用)时,将根据你的设计逐个使用该模式,否则将触发无限循环。对 deepFreeze()  的增强将是具有接收路径(例如Array)参数的内部函数,以便当对象进入不变时,可以递归地调用 deepFreeze() 。你仍然有冻结不应冻结的对象的风险,例如[window]。

// 深冻结函数.
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);
}obj2 = {internal: {}
};deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined

有一个要注意的点:

在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 TypeError。在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回。

> Object.freeze(1)
TypeError: 1 is not an object // ES5 code> Object.freeze(1)
1                             // ES2015 code

Object.freeze()的用处

对于纯展示的大数据,都可以使用Object.freeze提升性能。

Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改。

vue 1.0.18+对其提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换。

如果你有一个巨大的数组或Object,并且确信数据不会修改,使用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;// 下面两种做法,界面都会响应,Object.freeze()冻结的是值,你仍然可以将变量的引用替换掉。this.list = [{ value: 100 },{ value: 200 }];this.list = Object.freeze([{ value: 100 },{ value: 200 }]);}
})

本文参考:MDN--Object.freeze()  vue 实践心得和技巧

Object.freeze()相关推荐

  1. js object转数组_const 和 Object.freeze() 的区别 ?

    [送5本好书]你应该知道的 5 种 TypeScript设计模式 这篇文章介绍了使用const和Object.freeze()在 JS中定义常量和配置值一些做法,以及它们之间的区别. 当我们在 JS ...

  2. Object.freeze原来有这么大的作用

    一.Object.freeze可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性.可配置性.可写性.该方法返回被冻结 ...

  3. js中Object.freeze()函数的作用

    官方文档 Object.freeze() 方法可以冻结一个对象.一个被冻结的对象再也不能被修改:冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性.可配置性 ...

  4. Object.freeze()详解

    我们都知道const定义基本数据类型,这个值是不可以修改的.那么我们用const定义对象,可以修改对象吗? const a = 5 // a = 10 // TypeError: Assignment ...

  5. Object.freeze()--将对象冻结--在const中的应用

    被冻结的对象不能修改.添加.删除其属性或者属性值(freeze冻结的是堆内存中的值,和栈中的引用无关)--可以防止他人误改 <script> let c = {}; c.a="张 ...

  6. 前端性能优化-番外篇-Object.freeze到底用在哪

    对于前端纯大数据展示,不需要做修改其中字段等处理的,使用Object.freeze方法来包裹变量,vue内部不再去监听数据的变化提高性能. 话是这么说,官方资料这么写: https://develop ...

  7. js Object.freeze(obj)冻结一个对象或者一个数组,使其不能发生变化

    冻结一个对象或者一个数组,冻结的是对象本身冻结后的对象或者数组不能被修改不能添加新的属性 不能删除已有属性 不能修改已有属性的值返回值是被冻结的对象本身,与被冻结的源对象完全一致,也被冻结 let o ...

  8. Object.freeze()方法

    Object.freeze() 方法可以冻结一个对象.一个被冻结的对象再也不能被修改:冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性.可配置性.可写性, ...

  9. Object.freeze的使用

    定义 Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性.可配置性.可写性.该方 ...

最新文章

  1. S/4HANA生产订单增强WORKORDER_UPDATE方法BEFORE_UPDATE参数分析
  2. 时间序列总结.pptx
  3. Linux上磁盘热插拔
  4. 分页类实例 java
  5. 2018.10.29-2018.11.4
  6. 华中科技大学计算机系统结构,华中科技大学计算机系统结构考研
  7. Python学习之路day3-集合
  8. DTCMS自定义标签,获取所有栏目文章列表TOP,以及文章通用URL
  9. csdn如何修改文字体及颜色
  10. Atitit 运维之道 1.1.devops算是最低门槛了。什么运维平台,搞来搞去也就那些东西。无外乎cmdb、部署、监控之类的,再加点各种小平台自动化需求。 CMDB --Configurati
  11. Elasticseach api keys are not enabled
  12. Java工程师的成长之路
  13. 幂级数和函数经典例题_幂级数的和函数怎么求,做题有什么方法吗?
  14. 网站制作中关于版权声明的写法
  15. tomcat下的javaBean的配置
  16. 观李筱懿视频号有感:不要让所谓的大度变成对自己的道德绑架
  17. Network protocols
  18. 系统分析与设计HW4
  19. 业务架构、应用架构、数据架构、技术架构
  20. 2021年电工(初级)考试题及电工(初级)免费试题

热门文章

  1. 超强爆料:一位有良心的医生揭开献血内幕
  2. Vue知识(一)Vue基础语法
  3. 330tsl是什么意思_大众途观2015款车尾330tsl是什么意思
  4. python游戏源码——2绘画简易坦克
  5. 制作古装人物彩色工笔画图片的PS教程
  6. Android 和 iOS 实现录屏推流的方案整理
  7. 求助计算机程序员,程序员用代码求救:几近绝望时竟是老本行救了他
  8. scrapy_redis种子优化
  9. SOA:ESB 服务注册中心
  10. [DirectX 9.0笔记]第二章 渲染管线