如何将对象属性作为参数传递?(JavaScript)

36

我不确定标题是否适合我想要实现的内容。

我正在将 JSON 结果映射到数组中。因为我需要反复这样做,所以我想把代码放到一个函数中。

在下面的示例中,我在重复自己。我有一个叫做 item.data1、item.data2 的属性,在第二个示例中是 item.something1、item.something2...如何将这些属性作为“通用”的参数传递给新创建的函数,以便在那里使用它们而不必重复自己来返回这些映射?新函数应该可用于下面的两个示例以及其他属性可能具有不同名称的情况。

service.getData(function(data) {
    var map = {};
    map = $.map(data, function(item, i) {
        var entry = {};

        entry.key = item.data1;
        entry.value = item.data2;

        return entry;
    });
});

service.getSomething(function(data) {
    var map = {};
    map = $.map(data, function(item, i) {
        var entry = {};

        entry.key = item.something1;
        entry.value = item.something2;

        return entry;
    });
});

return {key:item.something1, value:item.something2} - Bergi
5个回答

65
使用[]和字符串一起可以动态地从对象中提取属性。
var a = { foo: 123 };
a.foo    // 123
a['foo'] // 123

var str = 'foo';
a[str]   // 123

这意味着我们可以像这样重构您的方法,只需将要读取的属性名称作为字符串传递进去即可。

var getKeyValueMap = function(data, keyPropName, valuePropName) {
  return $.map(data, function(item, i) {
    return {
      key:   item[keyPropName],
      value: item[valuePropName]
    }
  });
};

service.getData(function(data) {
  return getKeyValueMap(data, 'data1', 'data2');
});

service.getSomething(function(data) {
  return getKeyValueMap(data, 'something1', 'something2');
});

1
谢谢Alex。我开始认为JavaScript来自盟友是如此强大。 - Oscar Agreda
4
如果密钥有一层或两层嵌套,你该如何通过参数传递密钥? - LTroya
1
你只需要不断地钻研!obj[propA][propB][propC] - Alex Wayne

4

这可以通过使用 [] 运算符而非 . 符号来实现,就像我为您创建的这个fiddle一样:

    var data = [{
        data1: 'foo',
        data2: 'bar',
        something1: 'sparky',
        something2: 'arf arf!'},
    {
        data1: 'My name is',
        data2: 'What?',
        something1: 'my name is',
        something2: 'Who?!'}
    ];

    function test(data, prop) {
        var d_length = data.length;
        for (var i = 0; i < d_length; i++) {
            alert(data[i][prop]);
        }
    }

    test(data, 'data1');

1

您需要传递item对象和一个项目键到条目键的映射。这可以是两个数组、元组数组或者对象。我能想到的最简单的方法是将描述符对象更改为条目本身:

function mapPropertyNames(source, dest) {
    for (var prop in dest)
        dest[prop] = source[dest[prop]];
    return dest;
}

// and use it like this:

var map = $.map(data, function(item, i) {
    return mapPropertyNames(item, {key:"something1", value:"something2"});
});

1

类似于

service.getData(function(data) {
    var map = {};
    var varNamePrefix = 'data';
    map = $.map(data, function(item, i) {
        return getProperties(item, varNamePrefix);
    });
});

service.getSomething(function(data) {
    var map = {};
    var varNamePrefix = 'something';
    map = $.map(data, function(item, i) {
        return getProperties(item, varNamePrefix);
    });
});

function getProperties(item, varNamePrefix) {
    var ret = {};
    ret.key = item[varNamePrefix + '1'];
    ret.value = item[varNamePrefix + '2'];
    return ret;
}

需要帮忙吗?

基本上,您可以使用一个函数,它接受属性前缀并使用它来形成实际的属性名称以从项目中获取。


-1

试试这个:

service.getData(function(data, props) {// props is a property object
    var map = {};
    map = $.map(data, function(item, i) {
        var entry = {};

        for (var key in props) {
            entry[key] = item[key]
        }

        return entry;
    });
});

或者使用属性数组

service.getData(function(data, props) {// props is like ['data1', 'data2']
    var map = {};
    map = $.map(data, function(item, i) {
        var entry = {};

        for (var j = 0, k = props.length; j < k; j++) {
            entry[props[j]] = item[props[j]]
        }

        return entry;
    });
});

“property object” 究竟是什么意思? - Bergi
@Bergi 一个包含所需属性的对象,例如:{data1: 1, data2: 1} - dencey
这个不起作用,因为 "key" != "data1" - OP 想要属性被重命名。顺便说一下,你的数组答案更有意义... - Bergi
关键点是将属性作为参数传递给函数,您可以每次给出不同的值,参数的类型并不重要,选择一个您认为方便的即可。 - dencey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接