是否可以创建一个对象,其键与另一个对象匹配,值与函数输入参数匹配?
Is it possible to make an object with keys matching another object, values matching function input arguments?
想象中的代码和问题在这里:
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
};
示例输出
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 }
实际上,如果此信息有帮助,我正在尝试实现某种 redux 动作创建器。
也提供了一个(应该是)工作版本,但我想试试传播运算符:
function makeCreator(obj) {
return (...args) => {
let { type: obj.type, ...exceptType } = obj;
Object.keys(exceptType).forEach((key, index) => {
exceptType[key] = args[index];
});
return {
type: obj.type,
...exceptType,
};
}
}
从 ES2015 开始,可能,但这可能不是一个好主意。您可以使用 Object.getOwnPropertyNames
以稳定的顺序获取对象的字符串命名属性。顺序 稍微 复杂,但在您的示例中,顺序将是 type
、key1
和 key2
,因为
- 所有这些都是字符串键控的
- None 个匹配数组索引的定义(不,对象不是数组并不重要)
- None个是遗传的
- 这是创建属性的顺序
所以,又是可能:
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);
但是, 属性 order is new as of ES2015+ and that means older JavaScript engines don’不支持它(必须),它不能被 polyfilled。最好为您的 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);
回复您的评论:
I'd like to know if it's possible to make this work "only using" spread operator? Like what I demoed in the imagination part?
不,展开符号(它不是运算符)目前只能展开数组条目;在 ES2018(或现在通过转译器)中,它将能够传播对象属性及其值(因为该提案处于第 3 阶段并且可能会及时推进到 2018 规范中),但名称和值来自同一个对象。它不能从两个来源提取(一个地方的名称,另一个地方的值)。
想象中的代码和问题在这里:
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
};
示例输出
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 }
实际上,如果此信息有帮助,我正在尝试实现某种 redux 动作创建器。
也提供了一个(应该是)工作版本,但我想试试传播运算符:
function makeCreator(obj) {
return (...args) => {
let { type: obj.type, ...exceptType } = obj;
Object.keys(exceptType).forEach((key, index) => {
exceptType[key] = args[index];
});
return {
type: obj.type,
...exceptType,
};
}
}
从 ES2015 开始,可能,但这可能不是一个好主意。您可以使用 Object.getOwnPropertyNames
以稳定的顺序获取对象的字符串命名属性。顺序 稍微 复杂,但在您的示例中,顺序将是 type
、key1
和 key2
,因为
- 所有这些都是字符串键控的
- None 个匹配数组索引的定义(不,对象不是数组并不重要)
- None个是遗传的
- 这是创建属性的顺序
所以,又是可能:
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);
但是, 属性 order is new as of ES2015+ and that means older JavaScript engines don’不支持它(必须),它不能被 polyfilled。最好为您的 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);
回复您的评论:
I'd like to know if it's possible to make this work "only using" spread operator? Like what I demoed in the imagination part?
不,展开符号(它不是运算符)目前只能展开数组条目;在 ES2018(或现在通过转译器)中,它将能够传播对象属性及其值(因为该提案处于第 3 阶段并且可能会及时推进到 2018 规范中),但名称和值来自同一个对象。它不能从两个来源提取(一个地方的名称,另一个地方的值)。