如何动态更改对象的属性类型?

时间:2016-10-21 21:48:31

标签: javascript jquery arrays javascript-objects

我有JavaScript函数,它循环遍历span集合并动态创建一个对象。

<div id="container">
    <span class="property" data-propetyname="Day" data-propertyvalue="10"></span>
    <span class="property" data-propetyname="Year" data-propertyvalue="2015"></span>
    <span class="property" data-propetyname="Year" data-propertyvalue="2016"></span>
    <span class="property" data-propetyname="Month" data-propertyvalue="12"></span>
</div>


$(function ()
{
    function getData() {
        var data = {};
        $('#container').find('.property').each(function (index, value) {
            var property = $(value);
            var name = property.data('propetyname');
            var val = property.data('propertyvalue');
            data[name] = val;
        })

        return data;
    }
})

在上面的代码中,如果对象上已存在该属性,则它将覆盖该值。我想要的是,如果属性已经存在,那么它应该将属性的类型转换为数组并将值推入其中。例如,在上面的场景中,Year属性应该转换为包含2个值20152016的数组。

4 个答案:

答案 0 :(得分:3)

你可以这样做:

$(function ()
{
    function getData() {
        var data = {};
        $('#container').find('.property').each(function (index, value) {
            var property = $(value);
            var name = property.data('propetyname');
            var val = property.data('propertyvalue');

            if (!(name in data)) {
                data[name] = val; // new property
            } else if (data[name].constructor === Array) {
                data[name].push(val); // property is already an array
            } else {
               data[name] = [data[name], val]; // change property to array
            }
        })

        return data;
    }
})

答案 1 :(得分:2)

t2 != 0 => t1 = (/ t1 t2)*t2  .

注意$(function () { function getData() { var data = {}; $('#container').find('.property').each(function (index, value) { var property = $(value); var name = property.data('propetyname'); var val = property.data('propertyvalue'); if (data.hasOwnProperty(name)) { if (!Array.isArray(data[name])) { data[name] = [data[name]]; // convert to array! } data[name].push(val); } else { data[name] = val; } }) return data; } }) 仅存在于IE9 +中,否则使用其他阵列检测策略。

答案 2 :(得分:2)

首先,检查对象是否已具有该属性

if (data[name]) {

然后,检查对象是否已经是数组

  if(data[name].constructor === Array) {

如果是,您可以将值推送到数组。

      data[name].push(val);

否则

  } else {

将现有元素放入新数组,并将其分配给属性

    data[name] = [data[name],val];
  }

如果变量不是数组

} else {

只需为其指定val。

  data[name] = val;
}

那就是说,我认为对这段代码有一些可能的设计改进。首先,当您预期可能存在多个值时,我不会将单个元素存储为单个变量。您可以更轻松地将其存储为数组的第一个元素,然后您的分配代码将更加简单,访问此数组的代码也会更简单。

答案 3 :(得分:1)

这里有一个类似于其他建议的方法,使用普通的Javascript(没有jQuery requierd):

此解决方案执行以下操作:

  • 如果属性是一个数组,它只是将新元素推送到该数组。
  • 如果属性是字符串或数字,它会将该属性的值转换为包含一个元素(当前值)的数组,然后将新元素推送到该数组。
  • 如果该属性不存在,为空或为null,则只将该属性设置为新值。

(function() {
  function getData() {
    var data = {};

    var elements = document.querySelectorAll('#container .property'),
        i;

    for (i = 0; i < elements.length; i++) {
      var property = elements[i];
      var name = property.getAttribute('data-propertyname');
      var value = property.getAttribute('data-propertyvalue');


      if (data[name] instanceof Array) {
        data[name].push(value);
      } else if (typeof data[name] === 'string' || typeof data[name] === 'number') {
        data[name] = [data[name]];
        data[name].push(value);
      } else {
        data[name] = value;
      }
    }
    
    return data;
  }

  document.querySelector('pre').innerHTML = JSON.stringify(getData());
})();
<div id="container">
  <span class="property" data-propertyname="Day" data-propertyvalue="10"></span>
  <span class="property" data-propertyname="Year" data-propertyvalue="2015"></span>
  <span class="property" data-propertyname="Year" data-propertyvalue="2016"></span>
  <span class="property" data-propertyname="Month" data-propertyvalue="12"></span>
</div>

<pre></pre>