详解如何在Javascript中使用Object.freeze()

Object.freeze()

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

用法

const objectExample = {
 prop1: 20,
 prop2: "羊先生"
};

// 默认情况下,我们可以根据需要修改对象的属性
objectExample.prop1 = 100;
console.log(objectExample.prop1)

// 冻结对象
Object.freeze(objectExample);

objectExample.prop2 = "Alice" // 如果在严格模式会抛出失败,在非严格模式下只会抛出异常

console.log(objectExample.prop2);

结果

非严格模式

添加严格模式

"use strict";

抛出异常提示该属性是只读的

深度冻结

需要注意的是,如果被冻结的对象具有以对象作为值的属性,这些对象可以被更改

const theObject = {
 x: 1,
 z: 2,
 y: {
  a: "Hello",
  b: "羊先生"
 }
}

Object.freeze(theObject);

theObject.x = 100
console.log(theObject.x);

theObject.y.a = 'vipbic';
console.log(theObject.y.a);

结果

发现对象第一层是被冻结了,但是第二层并没有被冻结,这意味着我们只实现了「浅冻结」
要通过冻结对象的所有属性(包括那些将其他对象存储为值的属性)来使对象不可变,我们必须执行「深度冻结」—即使用递归在冻结父对象之前冻结子对象。

递归冻结

const theObject = {
 x: 1,
 z: 2,
 y: {
  a: "Hello",
  b: "羊先生"
 }
}

const deepFreeze = (obj) => {

 const propNames = Object.getOwnPropertyNames(obj)

 for (const name of propNames) {
  const value = obj[name];

  if (value && typeof value === "object") {
   deepFreeze(value);
  }
 }

 return Object.freeze(obj);
}

deepFreeze(theObject);
theObject.y.a = 100;
console.log(theObject.y.a );

结果

在Vue中使用Object.freeze

在vue2.0中,当你把一个普通的 JavaScript 对象传给 Vue 实例的  data  选项,Vue 将遍历此对象所有的属性,并使用  Object.defineProperty  把这些属性全部转为 getter/setter,这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化

有时在实际应用中,我们只是用来存储某个对象或者数组,并不要求它响应对应的视图,但在这个过程中vue还是会用object.defineProperty来监听这个数组,这样就是一种性能浪费,所以我们阔以使用Object.freeze来冻结数据

<h4 v-for="(item,idx) in items" :key="idx">{{ item.text }}</h4>
data() {
  let data = Object.freeze([{text:'羊先生'},{text:'ipbic'}])
  return {
    msg: '',
    items:data
  }
},
mounted() {

  this.items[0].text = '分享快乐'; // 界面不会更新

  this.items = [{ text: 'itnavs' },{ text: '分享快乐' }]; // 界面会更新

  this.items = Object.freeze([{ text: 'itnavs' },{ text: '分享快乐' }]); // 界面会更新
},

如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递增

使用Object.freeze从而避免这种资源的浪费,不要看它小,而忽略,不积跬步无以至千里

到此这篇关于详解如何在Javascript中使用Object.freeze()的文章就介绍到这了,更多相关Javascript Object.freeze()内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-10-17

JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析

本文实例讲述了JS Object.preventExtensions(),Object.seal()与Object.freeze()用法.分享给大家供大家参考,具体如下: 一.基本介绍 Method Description Param Detail Object.preventExtensions() 让一个对象变的不可扩展,也就是永远不能再添加新的属性 Object 详细 Object.isExtensible() 判断一个对象是否是可扩展 Object 详细 Object.seal() 让一

JS中call()和apply()的功能及用法实例分析

本文实例讲述了JS中call()和apply()的功能及用法.分享给大家供大家参考,具体如下: 1.call()和apply()的作用 首先引出问题:用call()和apply()的目的是什么? 来看个例子,在javascript OOP中,我们经常会这样定义: function cat(){ } cat.prototype={ food:"fish", say: function(){ alert("I love "+this.food); } } var bla

js中apply()和call()的区别与用法实例分析

本文实例讲述了js中apply()和call()的区别与用法.分享给大家供大家参考,具体如下: 每个函数都包括两个非继承而来的方法:apply()和call().两者用途都是在特定的作用域中调用函数,等于重新设置了函数体内this对象的值. 两者区别仅在于接收参数方式不同,apply()第一个参数是调用apply的函数运行的作用域,的第二个参数可以是Array的实例(数组),也可以是arguments对象,call()第一个参数是this的值没有变化,而其余参数都直接传递给函数(也就是逐个列举出

node.js中module模块的功能理解与用法实例分析

本文实例讲述了node.js中module模块的功能理解与用法.分享给大家供大家参考,具体如下: node.js中使用CommonJS规范实现模块功能,一个单独的文件就是一个单独的模块.通过require方法实现模块间的依赖管理. 通过require加载模块,是同步操作. 加载流程如下: 1.找到需要加载的模块文件. 2.判断是否缓存过,如果没有,则读取模块文件的内容. 3.把读取到的内容,封装在一个函数里运行. (function (exports, require, module, __fi

js构造函数constructor和原型prototype原理与用法实例分析

本文实例讲述了js构造函数constructor和原型prototype原理与用法.分享给大家供大家参考,具体如下: 所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型) 所有函数拥有prototype属性(显式原型)(仅限函数) 原型对象:拥有prototype属性的对象,在定义函数时就被创建 __proto__, prototype和constructor 下面这三个属性的定义非常重要,始终贯穿在原型中. prototype:此属性只有构造函数才有,它指向的是当前构造函数

Node.js API详解之 tty功能与用法实例分析

本文实例讲述了Node.js API详解之 tty功能与用法.分享给大家供大家参考,具体如下: tty 可以理解为终端的意思.tty 模块提供终端相关的接口,用来获取终端的行数列数等. 通过 const tty = require('tty'); 的方式引用 tty 模块 process.stdout.isTTY 说明: 此属性位于 process 模块,用来判断 Node.js 是否运行在一个 TTY 环境中 demo: console.log(process.stdout.isTTY) //

JavaScript对象拷贝与Object.assign用法实例分析

本文实例讲述了JavaScript对象拷贝与Object.assign用法.分享给大家供大家参考,具体如下: 深拷贝与浅拷贝 在 JavaScript 中,对于基本数据类型(undefined.null.boolean.number.string)来说,在变量中存储的就是这个变量本身的值,复制是对值的复制,不存在深浅之说.但C系语言的共同特点中有,存储引用类型(对象),实际中在变量里存的是它的地址.因此对 JavaScript 中的复杂数据类型(object)来说,也会有浅拷贝和深拷贝的概念:浅

JS扩展类,克隆对象与混合类实例分析

本文实例讲述了JS扩展类,克隆对象与混合类.分享给大家供大家参考,具体如下: 1.类扩展 /* EditInPlaceField类 */ /* 扩展函数 */ function extend(subClass, superClass) { var F = function() {}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass

Node.js API详解之 assert模块用法实例分析

本文实例讲述了Node.js API详解之 assert模块用法.分享给大家供大家参考,具体如下: Node.js API详解之 assert assert 模块提供了断言测试的函数,用于测试不变式. 断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真, 可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言. 同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言. 使用断言可以创建更稳定.品质更好且不易于出错的代码. 当需要在一个值为

js中this的用法实例分析

本文实例分析了js中this的用法.分享给大家供大家参考.具体分析如下: 实例1:第一种调用this的方法--以函数形式调用.它代表全局对象window 复制代码 代码如下: <script type="text/javascript"> function t(){  alert(this);//这里this表示window对象. } t(); </script> 实例2:第二种调用this的方法--以对象属性的形式调用.它代表该对象.实例中onclick为p元