Skip to content

对象操作

按需引入

如果未做全局配置,可以按需引入:

javascript
import { deepClone, deepMerge, getProperty, setProperty } from '@/node_modules/fusions-ui/libs/function/index.js';

注意

由于JS对象包括的范围非常广,加上ES6又有众多的新特性,很难做到囊括所有的类型和情况,也没必要;这里说的 对象 指的是普通的对象,不包括修改对象原型链,或者为 FunctionPromise 等情况。

对象深度克隆

场景:

  • 我们在平时开发可能会遇到需要通过 console.log 打印一个对象,至执行打印的时候,此对象为空,后面的逻辑中对此对象进行了修改赋值,但是我们在控制台直接看到的打印结果,却是修改后的值,这让人很困惑,虽然我们可以通过 console.log(JSON.parse(JSON.stringify(obj))) 的形式处理,但需要写这长长的一串,难免让人心生抵触。
  • 当我们将一个对象(变量A)赋值给另一个变量(变量B)时,修改变量B,因为对象引用的特性,导致A也同时被修改了,所有有时候我们需要将A克隆给B,再进行修改,这样就不会导致A也被修改了。
deepClone(object = {})
  • object 需要被克隆的对象
javascript
let A = {
    name: 'jack'
};

// 直接赋值,为对象引用,即修改B等于修改A,因为A和B为同一个值
let B = A;
B.name = 'lucy';
console.log(B); // {name: 'lucy'}
console.log(A); // {name: 'lucy'}

// 深度克隆,为新对象,修改B不影响A
let B = uni.$fu.deepClone(A);

B.name = 'lucy';
console.log(B); // {name: 'lucy'}
console.log(A); // {name: 'jack'}

对象深度合并

在ES6中,我们可以很方便的使用 Object.assign 进行对象合并,但这是浅层合并,如果对象的属性为数组或者对象的时候,会导致属性内部值的丢失。

注意

此处合并不同于 Object.assign,因为 Object.assign(A,B) 会修改 A 的值为最终的结果(这往往不是我们想要的),但是 deepMerge(A,B) 并不会修改 A 的值

deepMerge(target = {}, source = {})
  • target 目标对象
  • source 源对象

Object.assign 浅合并示例:

javascript
let A = {
    data: {
        name: 'jack'
    }
};

let B = {
    data: {
        sex: '男'
    }
};

// 使用 Object.assign 进行浅合并,注意此时的 A 被修改了
let C = Object.assign(A, B);

// 我们期望的结果是:
C = {
    data: {
        name: 'jack',
        sex: '男'
    }
}

// 我们实际得到的结果却是:
C = {
    data: {
        sex: '男'
    }
}

deepMerge 深度合并示例:

javascript
let A = {
    data: {
        name: 'jack'
    }
};

let B = {
    data: {
        sex: '男'
    }
};

// 使用 deepMerge 进行深度合并,注意此时的 A 不会被修改
let C = uni.$fu.deepMerge(A, B);

// C为我们期望的结果:
C = {
    data: {
        name: 'jack',
        sex: '男'
    }
}

getProperty(object, key)链式读取对象属性

读取属性时,我们需要从一个 对象 中进行操作,否则就会引起报错,因此 fusions-ui 提供了一个链式属性的读取方式。

当前,我们也可以使用 可选链操作符 的形式获取,但此方法在 Vue2template 中不适用。

javascript
// 假设有一个对象
const obj = {
    userInfo: {
        address: {
            city: '郑州市'
        }
    }
};

// 可以通过以下写法获取 city 属性
uni.$fu.getProperty(obj, 'userInfo.address.city'); // '郑州市'

// 也可选链操作符的形式
console.log(obj?.userInfo?.address?.city); // '郑州市'

setProperty(object, key, value)链式设置对象属性

设置属性时,我们需要从一个 对象 中进行操作,否则就会引起报错,因此 fusions-ui 提供了一个链式属性的设置方式。

javascript
// 假设有一个对象
const obj = {};

// 可以通过以下写法设置 city 属性
uni.$fu.setProperty(obj, 'userInfo.address.city', '郑州市');

// obj 将会变成以下对象结构:
{
    userInfo: {
        address: {
            city: '郑州市'
        }
    }
}