Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有条件地创建对象字段的简单方法?_Javascript - Fatal编程技术网

Javascript 有条件地创建对象字段的简单方法?

Javascript 有条件地创建对象字段的简单方法?,javascript,Javascript,我正在开发一个严重依赖数据输入的应用程序,因此我必须用必需和非必需的数据构建不同类型的对象,非必需的数据块是我的问题,因为这会导致大量额外的代码,我想知道是否有办法避免这种情况 这里我有一个表单,它有6个字段(这只是一个示例,但我在应用程序的许多其他地方也有相同的情况),其中2个是必需的,其余的不是,我编写了这个函数来处理对象创建: const handleAddSupplier = (e) => { e.preventDefault(); const formData

我正在开发一个严重依赖数据输入的应用程序,因此我必须用必需和非必需的数据构建不同类型的对象,非必需的数据块是我的问题,因为这会导致大量额外的代码,我想知道是否有办法避免这种情况

这里我有一个表单,它有6个字段(这只是一个示例,但我在应用程序的许多其他地方也有相同的情况),其中2个是必需的,其余的不是,我编写了这个函数来处理对象创建:

  const handleAddSupplier = (e) => {
    e.preventDefault();
    const formData = e.target.elements;

    const supplierData = {
      name: formData.name.value,
      companyId: formData.companyId.value,
      ...((formData.country.value || formData.city.value || formData.postalCode.value || formData.street.value) && {
        address: {
          ...(formData.country.value && { country: formData.country.value }),
          ...(formData.city.value && { city: formData.city.value }),
          ...(formData.postalCode.value && { postalCode: formData.postalCode.value }),
          ...(formData.street.value && { street: formData.street.value }),
        },
      }),
    };

    console.log(supplierData);
  };
它是可行的,但在我看来,代码太多了,我怀疑有一种更简单的方法可以做到这一点

必须创建的对象的“签名”是:

{
  name: "",
  companyId: "",
  address: {
    country: "",
    city: "",
    postalCode: "",
    street: ""
  }
}
address对象及其字段是完全可选的,因此如果没有可用的地址字段(即,用户只输入所需的字段而不输入其他内容),则根本不应创建address对象,甚至不应将其作为空对象创建

我的代码运行正常,我只是想看看是否还有其他更简单的方法

编辑:我对对象进行了一些解构,并为自己节省了一些文字,但是,如果我有10个非必填字段,我会有条件地“全部”还是“全部”10个呢

const { name, companyId, country, city, postalCode, street } = e.target.elements;

const supplierData = {
  name: name.value,
  companyId: companyId.value,
  ...((country.value || city.value || postalCode.value || street.value) && {
    address: {
      ...(country.value && { country: country.value }),
      ...(city.value && { city: city.value }),
      ...(postalCode.value && { postalCode: postalCode.value }),
      ...(street.value && { street: street.value }),
    },
  }),
};
或者用另一种方式写同样的东西:

const {
  name: { value: name },
  companyId: { value: companyId },
  country: { value: country },
  city: { value: city },
  postalCode: { value: postalCode },
  street: { value: street },
} = e.target.elements;

const supplierData = {
  name: name,
  companyId: companyId,
  ...((country || city || postalCode || street) && {
    address: {
      ...(country && { country }),
      ...(city && { city }),
      ...(postalCode && { postalCode }),
      ...(street && { street }),
    },
  }),
};
这就引出了一个问题,这只是一个“选择你的毒药”的场景吗?例如,在上一个场景中,在创建对象之前编写代码来分解结构并命名属性,然后在对象中,代码更简单、更易于阅读


这就引出了另一个问题,我正在寻找的优化,是否值得研究,或者坚持这两种方案中的任何一种都可以?

这里有一个在长度上非常相似的解决方案,但我认为这是:

  • 可读性更强
  • 使用新的可选字段轻松缩放

  • 您可以在循环中检查它们

    功能流程(e){
    设obj={}
    对于(让e.target.elements项){
    如果(item.value)obj[item.name]=item.value//应该正确检查它是否可以有有效的falsy值,为了简单起见,我把它留在这里
    }
    控制台日志(obj)
    }
    
    A:
    B:
    好啊
    
    我认为您已经通过解构尽可能优化了代码的长度。另一种保存代码的方法是使用实用程序函数(我建议使用这种函数,因为如果您经常使用这种解构向导,它们很容易出错)

    以下实用程序函数应允许您以更具声明性的方式选择值,确保不存在额外的值,并且省略空组。对于您创建的每个表单,只需要upper函数的一个变体(它相当简短且不言自明)

    const-handleAddSupplier=(e)=>{
    e、 预防默认值();
    常量值=formToValues(如目标值);
    常量供应商数据={
    …从(值,[“名称”,“公司ID]”)中选取,
    …optionalGroupFrom(值,“地址”[
    “国家”,
    “城市”,
    “邮政编码”,
    “街道”,
    ]),
    };
    控制台日志(供应商数据);
    };
    //实用程序函数(可以从其他文件导入)
    函数formToValues(表单){
    常量元素=form.elements;
    常量值={};
    for(元素中的常量名称)
    如果(元素[name].value)值[name]=元素[name].value;
    返回值;
    }
    常量optionalGroupFrom=(值、名称、键)=>{
    const group=pickFrom(值、键);
    const hasKeys=Object.keys(组).length!==0;
    如果(钥匙)返回{
    [名称]:集团
    };
    否则返回null;
    };
    常量pickFrom=(值、键)=>
    钥匙
    .map((键)=>({
    钥匙
    值:值[键]
    }))
    .filter((对)=>pair.value!==未定义)
    .reduce((映射,对)=>{
    控制台日志(map);
    map[pair.key]=pair.value;
    返回图;
    }, {});
    
    
    名称
    公司ID
    国家
    城市
    后代码
    街道

    问题中的
    e
    是否表示提交事件?@soimon是的,它是一个处理表单提交的函数。@appleapple将什么设置为未定义?我需要检查我是否有可用的值,如果我有,然后分配它们,这个特殊的检查就是我所说的,我的方法是“最简单”的方法,我最关心的是长或我必须做的,如果我有更多的字段,那将变长。这是一个表单,默认为空字符串,对不起。谢谢,我制作了一个小模型,足以回答问题。我喜欢这种方法,它不会直接起作用,因为我在表单中也有装饰元素,但可以在if检查中轻松处理,但这会使它成为一个普通的对象,我需要地址项位于
    address
    下的嵌套对象中,并且
    address
    不应作为空对象保留。如果没有地址项,则地址项应跟随我尝试的对象的isgnaturebuild@Darkbound只需将其添加到父对象即可:)其形式相同,该表单以“一个级别”的形式提供所有值,以便在嵌套对象中构造它们。父对象也由相同的值组成,基本上,所需的值是对象中的“级别1”,非所需的值是同一对象中嵌套对象中的“级别2”。请看我给出的示例。@Darkbound好吧,我所说的只是在我的示例中将
    obj
    分配给您的示例中的
    supplierData.address
    const handleAddSupplier = (e) => {
        e.preventDefault();
        const { name, companyId, country, city, postalCode, street } = e.target.elements;
    
        const supplierData = {
          name: formData.name.value,
          companyId: formData.companyId.value
        };
    
        const address = {
            country: (country || {}).value,
            city: (city || {}).value,
            postalCode: (postalCode || {}).value,
            street: (street || {}).value
        };
        Object.keys(address).forEach(key => {
            if (!address[key]) {  // Will catch null or undefined
                delete address[key];
            }
        });
    
        if (Object.keys(address).length) {
            supplierData.address = address;
        }
        console.log(supplierData);
      };