在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改

本文主要是介绍在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 一、Object.freeze()方法来冻结对象,防止对象被修改
        • 1、基本使用
        • 2、冻结数组
          • 2.1、浅冻结
          • 2.1、深冻结
        • 3、应用场景
        • 4、Vue中使用Object.freeze
      • 二、Object.assign()方法或展开语法(...)来合并对象
        • 1、Object.assign()
          • 1.1、语法
          • 1.2、参数
          • 1.3、示例
        • 2、展开语法Spread Operator (...)
        • 3、区别

一、Object.freeze()方法来冻结对象,防止对象被修改

Object.freeze() 是JavaScript中的一个方法,用于冻结一个对象。被冻结的对象不能再被修改。具体来说,它做了两件事情:

防止添加新的属性:尝试添加新属性将失败,不会抛出错误,但新属性不会被添加到对象中。
防止删除属性:尝试删除对象的任何属性都将失败,不会抛出错误。
但请注意,它不会防止修改对象已有的属性值。也就是说,你仍然可以更改、替换或修改对象上现有的属性。

我们都知道const定义基本数据类型,这个值是不可以修改的。那么我们用const定义对象,可以修改对象吗?

const a = 5
// a = 10  // TypeError: Assignment to constant variable.const obj = {name: '张三'
}
obj.name = '李四'
console.log(obj)    // {name: "李四"}

答案是肯定的。那么如果我们想定义一个不可被修改的对象,应该怎么办呢!
那就要用到Object.freeze()了。
它的作用是冻结一个对象,被冻结的对象有以下几个特性:

  • 不能添加新属性
  • 不能删除已有属性
  • 不能修改已有属性的值
  • 不能修改原型
  • 不能修改已有属性的可枚举性、可配置性、可写性
1、基本使用
var obj = {name: '张三',age: 18,address: '上海市'
}
obj.__proto__.habit = '运动'// 冻结对象
Object.freeze(obj)// 不能添加新属性
obj.sex = '男'
console.log(obj)    // {name: "张三", age: 18, address: "上海市"}// 不能删除原有属性
delete obj.age
console.log(obj)    // {name: "张三", age: 18, address: "上海市"}// 不能修改已有属性的值
obj.name = '李四'
console.log(obj)    // {name: "张三", age: 18, address: "上海市"}// 不能修改原型
obj.__proto__ = '随便什么值'
console.log(obj.__proto__)  // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}// 不能修改已有属性的可枚举性、可配置性、可写性
Object.defineProperty(obj,'address',{ // TypeError: Cannot redefine property: addressenumerable: false,// 表示是否可以枚举。直接在对象上定义的属性,基本默认trueconfigurable: false,// 表示能否通过delete删除属性,能否修改属性的特性writable: true// 表示能否修改属性的值。直接在对象上定义的属性,基本默认true
})

这里要注意一点,Object.freeze()的返回值就是被冻结的对象,该对象完全等于传入的对象,所以我们一般不需要接收返回值。上面我们对对象进行了冻结,那么我们可以冻结数组吗?

2、冻结数组
var arr = [1,2,3,4,5]
Object.freeze(arr)
arr[0]='新值'
console.log(arr)    // [1, 2, 3, 4, 5]

其实很容易能想明白,数组本质也就是对象,只不过对象的key是下标,所以也可以冻结。如果我的对象里还有对象呢,那么冻结是否依然有效?

2.1、浅冻结
var obj = {name: '张三',info: {a: 1,b: 2}
}
Object.freeze(obj)obj.name = '李四'
console.log(obj)    // {info: {a: 1, b: 2},name: "张三"}obj.info.a = 66
console.log(obj.info)   // {a: 66, b: 2}

可以看到对象中如果还有对象的时候,Object.freeze()失效了。Object.freeze()只支持浅冻结,下面我们封装一个深冻结函数,日后可直接使用

2.1、深冻结
var obj = {name: '张三',info: {a: 1,b: 2}
}function deepFreeze(obj) {// 获取所有属性var propNames = Object.getOwnPropertyNames(obj)// 遍历propNames.forEach(item => {var prop = obj[item]// 如果某个属性的属性值是对象,则递归调用if (prop instanceof Object && prop !== null) {deepFreeze(prop)}})// 冻结自身return Object.freeze(obj)
}deepFreeze(obj)obj.name = '李四'
console.log(obj)    // {name: "张三", info: {…}}obj.info.a = 100
console.log(obj.info)   // {a: 1, b: 2}
3、应用场景

Object.freeze()可以提高性能,如果你有一个对象,里面的内容特别特别多,而且都是一些静态数据,你确保不会修改它们,那你其实可以用Object.freeze()冻结起来,这样可以让性能大幅度提升,提升的效果随着数据量的递增而递增。一般什么时候用呢?对于纯展示的大数据,都可以使用Object.freeze提升性能。

4、Vue中使用Object.freeze

在vue项目中,data初始化 里面一般会有很多变量,后续如果不想使用它,可以使用Object.freeze()。这样可以避免vue初始化时候,做一些无用的操作,从而提高性能。

data(){return{list:Object.freeze({'我不需要改变'})}
}

二、Object.assign()方法或展开语法(…)来合并对象

在JavaScript中,你可以使用Object.assign()方法或者使用Spread Operator (…) 来合并对象。

1、Object.assign()

Object.assign() 静态方法将一个或者多个源对象中所有可枚举的自有属性复制到目标对象,并返回修改后的目标对象。

1.1、语法
Object.assign(target, ...sources)
1.2、参数
  • target:需要应用源对象属性的目标对象,修改后将作为返回值。

  • sources:一个或多个包含要应用的属性的源对象。

1.3、示例
let name = { name:'sea' },age = { age:15 },person= {}Object.assign(person,name,age)console.log(person) 
//{ name:'sea',age:15 }

在这个例子中,Object.assign()方法创建了一个新的对象,其属性是所有传入对象的属性的拷贝。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);
// Expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget === target);
// Expected output: true

如果目标对象与源对象具有相同的键(属性名),则目标对象中的属性将被源对象中的属性覆盖,后面的源对象的属性将类似地覆盖前面的源对象的同名属性。

2、展开语法Spread Operator (…)

浅拷贝 (Shallow-cloning,不包含 prototype) 和对象合并,可以使用更简短的展开语法。而不必再使用 Object.assign() 方式。

Spread运算符也可以用来合并对象。它可以将一个数组或对象展开到一个函数或数组中。

let name = { name:'sea' },age = { age:15 }let person = { ...name,...age }console.log(person)
//{ name:'sea',age:15 }

在这个例子中,Spread Operator (…) 用于扩展对象,所以它复制了所有对象的属性到新的对象中。

var obj1 = { foo: "bar", x: 42 };
var obj2 = { foo: "baz", y: 13 };var clonedObj = { ...obj1 };
// 克隆后的对象:{ foo: "bar", x: 42 }var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象:{ foo: "baz", x: 42, y: 13 }
3、区别
  • Object.assign() 函数会触发 setters,而展开语法则不会。

这篇关于在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/601413

相关文章

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

Python中的魔术方法__new__详解

《Python中的魔术方法__new__详解》:本文主要介绍Python中的魔术方法__new__的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、核心意义与机制1.1 构造过程原理1.2 与 __init__ 对比二、核心功能解析2.1 核心能力2.2

Python Transformer 库安装配置及使用方法

《PythonTransformer库安装配置及使用方法》HuggingFaceTransformers是自然语言处理(NLP)领域最流行的开源库之一,支持基于Transformer架构的预训练模... 目录python 中的 Transformer 库及使用方法一、库的概述二、安装与配置三、基础使用:Pi

关于pandas的read_csv方法使用解读

《关于pandas的read_csv方法使用解读》:本文主要介绍关于pandas的read_csv方法使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录pandas的read_csv方法解读read_csv中的参数基本参数通用解析参数空值处理相关参数时间处理相关

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

SpringBoot条件注解核心作用与使用场景详解

《SpringBoot条件注解核心作用与使用场景详解》SpringBoot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键,本文将系统梳理所有常用的条件注... 目录引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、@ConditionalOn

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Spring LDAP目录服务的使用示例

《SpringLDAP目录服务的使用示例》本文主要介绍了SpringLDAP目录服务的使用示例... 目录引言一、Spring LDAP基础二、LdapTemplate详解三、LDAP对象映射四、基本LDAP操作4.1 查询操作4.2 添加操作4.3 修改操作4.4 删除操作五、认证与授权六、高级特性与最佳

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S