是否可以使用匹配另一个对象的键创建一个对象,匹配函数输入参数的值?

时间:2017-08-28 09:42:45

标签: javascript ecmascript-6 spread-syntax

想象中的代码&问题在这里:

import org.apache.spark.sql.functions.col

df.groupBy("Col1 +: temp1 map col: _*)

示例输入

function makeCreator(obj) {
  return (...args) => {
    return {
      type: obj.type,
      ...obj.keys: ...args, 

      // the above is invalid js code, but I'd like 
      // the keys and values to be automatically paired
      ///////////////////////////////////////////////////////
      // Question: how to make it work using spread operator only?
      // I mean, is it possible to do everything with "just "the spread operator?
      ///////////////////////////////////////////////////////
    };
  }
}

示例输出

const obj1 = {
  type: 'something',
  key1: 10,
  key2: 20
};

实际上我正在尝试实现redux的某种动作创建器,如果这些信息有帮助的话。

还提供(应该是)工作版本,但我想尝试传播运算符:

const generatedForObj = makeCreator(obj1);

// it should equivalents to
function generatedForObj(v1, v2) {
  return {
    type: 'something',
    key1: v1,
    key2: v2,
  };
}

// use it like this
const result = generatedForObj (100, 200); 
// result is { type: 'something', key1: 100, key2: 200 }

1 个答案:

答案 0 :(得分:1)

它是可能的,从ES2015开始,但它可能不是一个好主意。您可以使用Object.getOwnPropertyNames以稳定的顺序获取对象的字符串命名属性。订单略微复杂,但在您的示例中,订单将为typekey1key2,因为

  1. 所有这些都是字符串键入的
  2. 它们都不匹配数组索引的定义(不,对象不是数组并不重要)
  3. 他们都没有被继承
  4. 这是创建属性的顺序
  5. 再说一遍,可能

    const makeCreator = obj => {
      const keys = Object.getOwnPropertyNames(obj).filter(key => key !== "type");
      return (...args) => {
        const result = {type: obj.type};
        keys.forEach((key, index) => {
          result[key] = args[index];
        });
        return result;
      }
    

    
    
    const obj1 = {
      type: 'something',
      key1: 10,
      key2: 20
    };
    
    const makeCreator = obj => {
      const keys = Object.getOwnPropertyNames(obj).filter(key => key !== "type");
      return (...args) => {
        const result = {type: obj.type};
        keys.forEach((key, index) => {
          result[key] = args[index];
        });
        return result;
      }
    };
    
    const generatedForObj = makeCreator(obj1);
    
    // use it like this
    const result = generatedForObj (100, 200); 
    console.log(result);
    
    
    

    但是 ,从ES2015 +开始,属性顺序是新的,这意味着较旧的JavaScript引擎不支持它(必然),并且无法进行多边形填充。最好明确提供makeCreator一组属性名称:

    const makeCreator = (obj, keys) => {
      return (...args) => {
        const result = {type: obj.type};
        keys.forEach((key, index) => {
          result[key] = args[index];
        });
        return result;
      }
    };
    

    用法:

    const generatedForObj = makeCreator(obj1, ["key1", "key2"]);
    

    
    
    const obj1 = {
      type: 'something',
      key1: 10,
      key2: 20
    };
    
    const makeCreator = (obj, keys) => {
      return (...args) => {
        const result = {type: obj.type};
        keys.forEach((key, index) => {
          result[key] = args[index];
        });
        return result;
      }
    };
    
    const generatedForObj = makeCreator(obj1, ["key1", "key2"]);
    
    // use it like this
    const result = generatedForObj (100, 200); 
    console.log(result);
    
    
    

    重新评论:

      

    我想知道是否可以完成这项工作"仅使用"传播运营商?就像我在想象部分演示的那样?

    不,传播符号(它不是运营商)现在只能传播数组条目;在ES2018(或现在通过转换器),它将能够传播对象属性及其值(因为该提议处于第3阶段,可能会在2018年规范中及时推进),但名称和值来自同一个对象。它不能从两个来源(一个地方的名字,另一个地方的价值)中抽取。