网站首页 > 技术文章 正文
前言
众所周知,在JavaScript中我们使用const声明一个常量时,一旦声明后就不能再重新赋值。但如果是对象或者是数组的属性与元素是可以被修改的。
那么怎么让const定义的对象的属性也不能被修改呢?? 太简单了,下面会区别情况进行讲解与演示。
基本示例
其实很简单就看你有没有想到了,主要还是考验对API的运用是否熟练,我们只需要结合使用Object.freeze()方法就可以实现了,Object.freeze()可以冻结对象,但只能冻结第一层属性。
因此我们先看看一层的对象示例
<html lang="zh">
<head>
<script>
const testobj = {
name: "天天鸭",
age: 88,
};
Object.freeze(testobj);
// 添加
testobj["newgen"] = "new天";
console.log("添加属性:", testobj.newgen);
// 删除
delete testobj.age;
console.log("删除属性:", testobj.age);
// 修改
testobj.name = "月月鸭";
console.log("修改属性:", testobj.name);
</script>
</head>
<body>
您好,我是天天鸭的示例
</body>
</html>先用const结合Object.freeze()后对其进行增删改操作,下面看看对应的打印效果
看效果可以知道增删改都不会生效并且不会输出任何错误,并且如果是添加会输出undefined。
注意: 如果是严格模式会报错,如下图片所示。
在Vue框架中示例
如果在Vue3框架演示呢,你们觉得会有什么区别不???
下面直接上一个例子再说吧
<template>
<div></div>
</template>
<script setup>
const testobj = {
name: "天天鸭",
age: 88,
};
Object.freeze(testobj);
// 添加
testobj["newgen"] = "new天";
console.log("添加属性:", testobj.newgen);
// 删除
delete testobj.age;
console.log("删除属性:", testobj.age);
// 修改
testobj.name = "月月鸭";
console.log("修改属性:", testobj.name);
</script>在Vue3中先用const结合Object.freeze()后对其进行增删改操作,再看看下面打印出来的效果
啊这....怎么来到这里就直接报错了呢??? 你们知道为什么不
其实原因有二
一、是Vue 在开发模式下会默认使用严格模式,从而会导致报错。
二、是因为与Vue框架的响应式和生命周期相关的原因,Vue的响应式机制会对对象进行依赖收集处理,从而实现响应式效果。当我们用Object.freeze冻结时,Vue会无法执行这些处理,因为已经冻结不可扩展了。
层级复杂的对象
我们日常使用对象处理数据的情况下不可能都是一层的简单结构,如果是层级很复杂的树状结构呢??毕竟Object.freeze()只能冻结一层。
那当然是用递归了,看看下面例子
<html lang="zh">
<head>
<script>
function deepObjFreeze(obj) {
// 如果已经是冻结的
if (Object.isFrozen(obj)) {
return obj;
}
// 获取所有属性
const keys = Object.keys(obj);
// 冻结每个
keys.forEach((key) => {
const value = obj[key];
if (value && typeof value === "object" && !Object.isFrozen(value)) {
deepObjFreeze(value);
}
});
// 冻结当前
return Object.freeze(obj);
}
const testObj = {
name: "天天鸭",
age: 88,
details: {
age: 25,
gender: "new天",
},
};
const frozenObj = deepObjFreeze(testObj);
// 尝试修改属性
frozenObj.name = "new名";
frozenObj.details.age = 30;
console.log(frozenObj);
</script>
</head>
<body>
您好,我是天天鸭的示例
</body>
</html>递归冻结后我们再去修改里面的属性,效果打印出来如下所示,不受任何影响。
小结
突然灵感一来,想起这个很考验基本功的小问题,没有难度,就是考我们对Object.freeze()方法的熟悉和结合需求的灵活性。
好啦文章这到这里,如果哪里写的不对或者有更好的建议欢迎指出哦。
原文链接:https://juejin.cn/post/7440855355549974547
- 上一篇: JS遍历(循环)——JS对象&JS数组
- 下一篇: JS数组和对象相互转换方法「实用」
猜你喜欢
- 2024-12-15 JavaScript 数据结构-对象详解(一)
- 2024-12-15 JavaScript 即将迎来新特性: Array.zip 和 Array.zipKeyed
- 2024-12-15 数组遍历归纳 数组遍历归纳思维导图
- 2024-12-15 JS数组和对象相互转换方法「实用」
- 2024-12-15 JS遍历(循环)——JS对象&JS数组
- 2024-12-15 Vue进阶(三十五):vue中watch详细用法
- 2024-12-15 Worksheet对象之应用进阶 worksheet function
- 2024-12-15 php 用数组语法访问对象属性 php 用数组语法访问对象属性怎么写
- 11-21win7怎么连接无线网wifi(win7怎么连接无线网络连接)
- 11-21u盘启动盘制作视频教程(u盘启动盘怎么制作)
- 11-21微软商店官网入口(微软官方商城app)
- 11-20怎么卸载电脑上的软件(没有360怎么卸载电脑上的软件)
- 11-20最靠谱的安装驱动软件(安装驱动什么软件好用)
- 11-20笔记本无法连接网络怎么解决
- 11-20电脑硬盘坏了值得修吗(电脑硬盘坏了能修吗多少钱一个)
- 11-20电脑防火墙点击无反应(电脑防火墙点击无反应怎么办)
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (77)
- vector线程安全吗 (73)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)
