在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

相关文章

检查 Nginx 是否启动的几种方法

《检查Nginx是否启动的几种方法》本文主要介绍了检查Nginx是否启动的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1. 使用 systemctl 命令(推荐)2. 使用 service 命令3. 检查进程是否存在4

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程