【问题标题】:How to dynamically change object's property type?如何动态更改对象的属性类型?
【发布时间】:2017-03-04 07:29:14
【问题描述】:

我有 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 属性应转换为具有两个值 20152016 的数组。

【问题讨论】:

    标签: javascript jquery arrays javascript-objects


    【解决方案1】:

    你可以这样做:

    $(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;
        }
    })
    

    【讨论】:

      【解决方案2】:
      $(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;
          }
      })
      

      注意Array.isArray 仅存在于 IE9+ 中,否则使用其他数组检测策略。

      【讨论】:

        【解决方案3】:

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

        if (data[name]) {
        

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

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

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

              data[name].push(val);
        

        否则

          } else {
        

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

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

        如果变量还不是数组

        } else {
        

        只需将 val 分配给它。

          data[name] = val;
        }
        

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

        【讨论】:

          【解决方案4】:

          这是与其他建议类似的方法,使用纯 Javascript(不需要 jQuery):

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

          • 如果属性是一个数组,它只是将新元素推送到该数组。
          • 如果属性是字符串或数字,它会将该属性的值转换为具有一个元素(当前值)的数组,然后将新元素推送到该数组。
          • 如果该属性不存在、为空或 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>

          【讨论】:

            猜你喜欢
            • 2023-02-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多