添加动态属性

给对象添加属性,名称动态变化怎么办?

  1. let obj = {};
  2. let index = 1;
  3. let key = `topic${index}`;
  4. obj[key] = 'topic';

ES6 中的对象属性名可以使用表达式,不用创建一个额外的变量

  1. let obj = {};
  2. let index = 1;
  3. obj[`topic${index}`] = 'topic';

Object对象转化为表单FormData对象

  1. /**
  2. * 对象转化为formdata
  3. * @param {Object} object
  4. */
  5. export function getFormData(object) {
  6. const formData = new FormData()
  7. Object.keys(object).forEach(key => {
  8. const value = object[key]
  9. if (Array.isArray(value)) {
  10. value.forEach((subValue, i) =>
  11. formData.append(key + `[${i}]`, subValue)
  12. )
  13. } else {
  14. formData.append(key, object[key])
  15. }
  16. })
  17. return formData
  18. }

使用场景:上传文件时我们要新建一个FormData对象,然后有多少个参数就append多少次,使用该函数可以简化逻辑。使用:

  1. let req={
  2. file:xxx,
  3. userId:1,
  4. phone:'15198763636',
  5. //...
  6. }
  7. fetch(getFormData(req))

表单FormData对象转化为Object对象

  1. const formToObject = form =>
  2. Array.from(new FormData(form)).reduce(
  3. (acc, [key, value]) => ({
  4. ...acc,
  5. [key]: value
  6. }),
  7. {}
  8. );
  9. formToObject(document.querySelector('#form'));
  10. // { email: 'test@email.com', name: 'Test Name' }

深拷贝

  1. function deepClone(obj, hash = new WeakMap()) {
  2. if (obj === null) return obj;
  3. // 如果是null或者undefined我就不进行拷贝操作
  4. if (obj instanceof Date) return new Date(obj);
  5. if (obj instanceof RegExp) return new RegExp(obj);
  6. // 可能是对象或者普通的值 如果是函数的话是不需要深拷贝
  7. if (typeof obj !== "object") return obj;
  8. // 是对象的话就要进行深拷贝
  9. if (hash.get(obj)) return hash.get(obj);
  10. let cloneObj = new obj.constructor();
  11. // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
  12. hash.set(obj, cloneObj);
  13. for (let key in obj) {
  14. if (obj.hasOwnProperty(key)) {
  15. // 实现一个递归拷贝
  16. cloneObj[key] = deepClone(obj[key], hash);
  17. }
  18. }
  19. return cloneObj;
  20. }
  21. let obj = { name: 1, address: { x: 100 } };
  22. obj.o = obj; // 对象存在循环引用的情况
  23. let d = deepClone(obj);
  24. obj.address.x = 200;
  25. console.log(d);
  1. // from https://www.30secondsofcode.org/js/s/deep-clone/
  2. const deepClone = obj => {
  3. if (obj === null) return null;
  4. let clone = Object.assign({}, obj);
  5. Object.keys(clone).forEach(
  6. key =>
  7. (clone[key] =
  8. typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  9. );
  10. if (Array.isArray(obj)) {
  11. clone.length = obj.length;
  12. return Array.from(clone);
  13. }
  14. return clone;
  15. };
  16. const a = { foo: 'bar', obj: { a: 1, b: 2 } };
  17. const b = deepClone(a); // a !== b, a.obj !== b.obj

deepMerge

https://github.com/vuejs/create-vue/blob/main/utils/deepMerge.ts

  1. const isObject = (val) => val && typeof val === 'object'
  2. const mergeArrayWithDedupe = (a, b) => Array.from(new Set([...a, ...b]))
  3. /**
  4. * Recursively merge the content of the new object to the existing one
  5. * @param {Object} target the existing object
  6. * @param {Object} obj the new object
  7. */
  8. function deepMerge(target, obj) {
  9. for (const key of Object.keys(obj)) {
  10. const oldVal = target[key]
  11. const newVal = obj[key]
  12. if (Array.isArray(oldVal) && Array.isArray(newVal)) {
  13. target[key] = mergeArrayWithDedupe(oldVal, newVal)
  14. } else if (isObject(oldVal) && isObject(newVal)) {
  15. target[key] = deepMerge(oldVal, newVal)
  16. } else {
  17. target[key] = newVal
  18. }
  19. }
  20. return target
  21. }
  22. export default deepMerge