jQuery()对象可以保存非DOM对象吗?

时间:2016-03-17 01:13:26

标签: jquery

分析this SO question显示的代码,我刚刚注意到它使用jQuery迭代JSON数组的方式:

$(data).each(function() {

虽然我认为数组应该以这种方式迭代:

$.each(data, function() {

确实,jQuery.each() manual page州:

  

$ .each()函数与$(selector).each()不同,后者用于独占于jQuery对象进行迭代。

但是由于OP似乎让他的代码至少部分工作,我很想测试,并发现它有效!
以下是证据:

var data = [
  {"key": "value-1"},
  {"key": "value-2"},
  {"key": "value-3"}
];

$(data).each(function() {
  document.write('<br />' + this.key);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

因此,如果$(data).each()data是JSON数组时有效,那么这似乎意味着此数组是$(data)返回jQuery对象的可接受内容。

然后进行调查我检查了jQuery(elementArray) manual page并查看了jQuery( elementArray )部分,其中指出:

  

elementArray
  类型:数组
  一个数组,包含一组DOM元素以包装在jQuery对象中。

根据以上所述,对象数组(而不是DOM元素)应该失败 所以我测试了比较这个$(data)和简单$('body')返回的对象。结果如下:

var data = [
  {"key": "value-1"},
  {"key": "value-2"},
  {"key": "value-3"}
];

function log(obj, init) {
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      var $row = $('tr[data-prop=' + prop + ']');
      if (!$row.length) {
        $row =
          $('<tr data-prop="' + prop + '"><th>' + prop + '</th></tr>')
          .appendTo($('table'));
        if (!init) {
          $row.append('<td></td>');
        }
      }
      $row.append('<td>' + JSON.stringify(obj[prop]).substr(0,25) + '</td>');
    }
  }
}

log($('body'), true);
log($(data), false);
table {
  border-collapse: collapse;
  border: 1px solid #000;
}
th, td {
  border: 1px solid #000;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <th>Property</th>
    <th>$('body')</th>
    <th>$(data)</th>
  </tr>
</table>

实际上似乎所有东西都可以转换为jQuery对象 我很困惑:我是不是重新发明轮子了??

2 个答案:

答案 0 :(得分:1)

您过多地阅读了文档。

是的,通常jQuery(elementArray)将用于元素数组中。但是,它可以是一系列任何东西。

intent 是您在具有普通元素的数组上使用$.each()和可能的其他便捷方法。您会发现,如果您的数组没有某种元素,则其他jQuery方法不会匹配数组中的任何内容。

答案 1 :(得分:1)

是的,jQuery构造函数接受一个数组,您可以使用$.fn.each方法遍历返回的jQuery集合,并且处理程序中的this引用每个元素。 jQuery集合是array-like对象。

但是,不,这并不意味着您可以成功调用集合上所有与DOM相关的方法。只需尝试$(data).html()作为示例,您将收到错误,因为它希望看到 DOM节点而不是普通对象或集合中的字符串。

另一个例子是尝试$(['foo']).text()并在jQuery 2.2.2中抛出Uncaught RangeError: Maximum call stack size exceeded错误。

现在尝试:

/**
 * `text` reads textContent of DOM elements (nodeType = 1)
 * and `nodeValue` of textNodes (nodeType = 3) 
 * and returns the concatenated text
 */
$([
  { "nodeType": 1, "textContent": "value-1" },
  { "nodeType": 3, "nodeValue": "value-2" },
  { "textContent": "I'm a rebel" }
]).text()

然后返回"value-1value-2"