首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

不可变的JS -将值提取到数组

基础概念

不可变(Immutable)在JavaScript中指的是一旦某个值被创建,就不能再被改变。在函数式编程中,不可变性是一个核心概念,它有助于减少副作用和提高代码的可预测性。

相关优势

  1. 减少副作用:不可变数据结构不会因为外部操作而改变,这使得代码更容易理解和调试。
  2. 提高并发性能:由于不可变数据结构不会改变,多个线程可以安全地共享这些数据,而不需要复杂的锁机制。
  3. 简化代码逻辑:不可变数据结构使得代码逻辑更加清晰,因为你可以确定数据在任何时候都不会改变。

类型

在JavaScript中,不可变数据结构可以通过以下几种方式实现:

  1. 原始值:如数字、字符串和布尔值,它们本身就是不可变的。
  2. 冻结对象:使用Object.freeze()方法可以冻结一个对象,使其属性不可修改。
  3. 库提供的不可变数据结构:如Immutable.js、Immer等。

应用场景

  1. 状态管理:在React等前端框架中,使用不可变数据结构可以更好地管理组件状态。
  2. 并发编程:在多线程或多进程环境中,不可变数据结构可以减少竞态条件和数据冲突。
  3. 函数式编程:不可变数据结构是函数式编程的基础,有助于编写纯函数和高阶函数。

示例代码

假设我们有一个对象,我们希望将其值提取到一个数组中,并且保持原始对象的不可变性。

代码语言:txt
复制
// 原始对象
const originalObject = {
  name: 'Alice',
  age: 30,
  city: 'Wonderland'
};

// 使用Object.freeze()冻结对象
const frozenObject = Object.freeze(originalObject);

// 提取值到数组
const valuesArray = Object.values(frozenObject);

console.log(valuesArray); // 输出: ['Alice', 30, 'Wonderland']

遇到的问题及解决方法

问题:为什么使用Object.freeze()后,对象的属性仍然可以被修改?

原因Object.freeze()只能冻结对象本身的属性,如果对象的属性是对象,那么这个嵌套的对象不会被冻结。

解决方法:递归地冻结对象的所有嵌套属性。

代码语言:txt
复制
function deepFreeze(obj) {
  // 首先冻结当前对象
  Object.freeze(obj);
  // 遍历对象的每个属性
  Object.keys(obj).forEach((key) => {
    const value = obj[key];
    // 如果属性值是对象,递归冻结
    if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {
      deepFreeze(value);
    }
  });
}

const originalObject = {
  name: 'Alice',
  age: 30,
  address: {
    city: 'Wonderland',
    zip: '12345'
  }
};

const deeplyFrozenObject = deepFreeze(originalObject);

// 尝试修改嵌套对象的属性
deeplyFrozenObject.address.city = 'New Wonderland'; // 不会生效

console.log(deeplyFrozenObject.address.city); // 输出: 'Wonderland'

参考链接

希望这些信息对你有所帮助!

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • js中如何判断数组中包含某个特定_js数组是否包含某个

    array.indexOf 判断数组中是否存在某个,如果存在返回数组元素下标,否则返回-1 let arr = ['something', 'anything', 'nothing',...anything']; let index = arr.indexOf('nothing'); # 结果:2 array.includes(searchElement[, fromIndex]) 判断一个数组是否包含一个指定...参数:searchElement 需要查找元素。 参数:thisArg(可选) 从该索引处开始查找 searchElement。...numbers.includes(8); # 结果: true result = numbers.includes(118); # 结果: false array.find(callback[, thisArg]) 返回数组中满足条件第一个元素...方法,该方法返回元素在数组下标,如果不存在与数组中,那么返回-1; 参数:searchElement 需要查找元素

    18.4K40

    JS 面试之数组几个 low 操作

    前言 本文主要从应用来讲数组api一些骚操作,如一行代码扁平化n维数组数组去重、求数组最大数组求和、排序、对象和数组转化等。 上面这些应用场景你可以用一行代码实现吗?...Array.from是数组转化为数组。 ...是扩展运算符,set里面的转化为字符串。...reduce是ES5数组api,参数有函数和默认初始。 函数有四个参数: pre:上一次返回 cur:当前 curIndex:当前索引 arr:当前数组 2.开始篇 先排序再取值。...call、 apply:改变 slice里面的 this指向 arguments,所以 arguments也可调用数组方法。 Array.from:类似数组或可迭代对象创建为数组。 ......:数组扩展为字符串,再定义为数组

    1.2K30

    JS面试之数组几个low操作(3)

    序列文章 JS面试之函数(1) JS面试之对象(2) 前言 本文主要从应用来讲数组api一些骚操作; 如一行代码扁平化n维数组数组去重、求数组最大数组求和、排序、对象和数组转化等; 上面这些应用场景你可以用一行代码实现...Array.from是数组转化为数组 ...是扩展运算符,set里面的转化为字符串 2.开始篇 Array.prototype.distinct = nums => { const map =...,参数是字符串; reduce是ES5数组api,参数有函数和默认初始; 函数有四个参数,pre(上一次返回),cur(当前),curIndex(当前索引),arr(当前数组) 2.开始篇...item===3 }) //true 如果包含返回false 8.类数组转化 1.终极篇 Array.prototype.slice.call(arguments) //arguments是类数组(...call,apply:是改变slice里面的this指向arguments,所以arguments也可调用数组方法 Array.from是类似数组或可迭代对象创建为数组 ...是数组扩展为字符串

    1.2K20

    查找排序数组最小(js)

    题目 在由小到大已排序未知数组中,以某个元素为支点旋转(好比序列沿着前后顺序围成环移动)得到了一个数组,请找出该数组最小。...比如倘若原数组(对我们而言,并不知道原数组是什么)为0,1,2,3,4,5,6,7,可能经过旋转后得到数组 3,4,5,6,7,0,1,2。请找出旋转后数组最小(假定数组中没有重复数字)。...从旋转点分开两段数组都是有序,而且前面数组都要大于后边子数组元素,所以要找旋转后数组最小也就是两个有序数组分界线。...所以有点像数学中夹逼准则,有两个指针分别从数组开头和结尾想目的地不断逼近,直到缩小范围成为一个点,则是目标值。...,arr[mid]不可能是最小 9 start=mid+1 10} 11else { 12 // 对于原本升序数组,此时arr[mid]有可能是最小 13 end= mid 14

    2.9K40

    Js数组对象中某个属性升序排序,并指定数组某个对象移动到数组最前面

    需求整理:   本篇文章主要实现一个数组中对象属性通过升序方式排序,然后能够让程序可以指定对应数组对象移动到程序最前面。...: 23},{name: "小芳", Id: 18}];   首先把数组Id通过升序方式排序: //源数组 var arrayData= [{name: "夏明", Id:24}, {name:..., Id: 24 },{ name: "小红", Id: 25 }] 找到Id为23对象,移动到数组最前面去(注意Id唯一): 实现原理:因为移除数组对象需要找到对应数组对象下标索引才能进行移除...,现在我们需要移除Id=23对象,让其排到最前面去(先找到对象下标,然后把给数组对象赋值给temporaryArry临时数组,然后在通过下标移除newArrayData中该对象,最后arrayData...v=>v.Id==23); console.log('Id=23索引为:',currentIdx); //把Id=23对象赋值给临时数组 temporaryArry.push(newArrayData

    12.3K20

    js中关于假和空数组总结

    如果Type(x)是布尔,返回ToNumber(x) == y结果。 如果Type(y)是布尔,返回x == ToNumber(y)结果。...2、对于空数组和空对象疑惑 疑惑来源:用空数组和空对象进行if语句判断为true,但是空数组和true进行==运算时,返回是false 用代码表示: if([]){ console.log(...'空数组转化为布尔为true');//空数组转化为布尔为true } if({}){ console.log('空对象转化为布尔为true');//空对象转化为布尔为true } if(...[]==true){ console.log('空数组等于true'); }else{ console.log('空数组等于false');//空数组等于false } 为什么空数组转化为布尔是...[ ]会先调用valueOf方法,返回数组本身不是原始,所以继续调用toString方法,返回' ',从而Number(' ')=0,而0!=1,所以返回false。

    5.1K30

    js数组添加数据方式js数组对象中添加属性和属性

    参考:https://www.cnblogs.com/ayaa/p/14732349.html js数组添加数据方式有以下几种: 直接利用数组下标赋值来增加(数组下标起始是0) 例,先存在一个有...(5,8,9); console.log(arr);  此时输出结果是[ 1, 2, 3, 5, 8, 9 ]; 通过 数组名.unshift(参数)来增加从数组第1个数据开始参数,unshift可以带多个参...用 数组名.splice(开始插入下标数,0,需要插入参数1,需要插入参数2,需要插入参数3……)来增加数组数据 let arr=[1,2,3]; //splice(第一个必需参数:该参数是开始插入...\删除数组元素下标,第二个为可选参数:规定应该删除多少元素,如果未规定此参数,则删除从 第一个参数 开始到原数组结尾所有元素,第三个参数为可选参数:要添加到数组新元素) let result=arr.splice...(3,0,7,8,9) console.log(arr);  此时输出结果是[ 1, 2, 3, 7, 8, 9 ]; 因为举例是从第3个下标开始,所以是直接在数组最后开始增加数组内容; js数组对象中添加属性和属性

    23.4K20
    领券