Javascript数组过滤器:获取正确的上下文

Javascript array filter: getting the context right

本文关键字:上下文 获取 数组 过滤器 Javascript      更新时间:2024-01-21

在尝试编写一些很棒的JS时,我遇到了一些奇怪的JS行为。我创建了一段代码来演示我的问题:

http://jsfiddle.net/CeyCy/

<html>
  <head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
      var images = $('.images').children();
      var filtered = images.filter(function(i, image) {
        console.log(this);
      }, "abc");
    });
    </script>
  </head>
  <body>
    <div class="options">
      <div class="filters">
      </div>
      <ol class="pagination">
      </ol>
    </div>
    <div class="results">
      <ul class="images">
        <li data-category="Zakelijk">Result 1</li>
        <li data-category="Speels">Result 2</li>
        <li data-category="Blogging">Result 3</li>
        <li data-category="Zakelijk">Result 4</li>
        <li data-category="Speels">Result 5</li>
        <li data-category="Blogging">Result 6</li>
        <li data-category="Zakelijk">Result 7</li>
        <li data-category="Speels">Result 8</li>
        <li data-category="Blogging">Result 9</li>
        <li data-category="Zakelijk">Result 10</li>
        <li data-category="Speels">Result 11</li>
        <li data-category="Blogging">Result 12</li>
        <li data-category="Zakelijk">Result 13</li>
        <li data-category="Speels">Result 14</li>
        <li data-category="Blogging">Result 15</li>
      </ul>
    </div>
  </body>
</html>

好的,现在是我的问题。使用Array.filter方法时,将回调函数作为第一个参数,并将可选上下文作为第二个参数。正如你所看到的,我把"abc"作为上下文传递(当然,这很荒谬)。我希望我的控制台会抛出很多"abc",但它会打印jQuery元素!

有人能照一下这个吗?

谢谢,

Martijn

正如你所看到的,我把"abc"作为上下文传递(当然,这很荒谬)。我希望我的控制台会抛出很多"abc",但它会打印jQuery元素!

您使用的是jQuery的filter,它没有上下文参数,而不是ES5的Array#filter,因为您在jQuery对象上调用filter,而jQuery对象不是数组(尽管它们提供了很多类似数组的功能,以及几个名称相似的"方法",包括filter)。

三个选项供您选择:

makeArray

您可以使用jQuery的makeArray将jQuery对象转换为数组,例如:

$(function() {
  var images = $.makeArray($('.images').children());
  var filtered = images.filter(function(i, image) {
    console.log(this);
  }, "abc");
});

更新的fiddle

proxy/bind

或者,您可以使用jQuery的proxy函数(或ES5的Function#bind)将要传递的迭代器函数绑定到jQuery的filter,这样它就会忽略jQuery提供的this

$(function() {
  var images = $('.images').children();
  var filtered = images.filter($.proxy(function(i, image) {
    console.log(this);
  }, "abc"));
});

Array#filter应用于jQuery对象

或者您可以将Array#filter直接应用于jQuery对象:

$(function() {
  var images = $('.images').children();
  var filtered = Array.prototype.filter.call(images, function(i, image) {
    console.log(this);
  }, "abc");
});

因为Array#filter明确定义的,可以处理任何类似数组的东西,而不仅仅是Arrays。最后一种可能实际上是最有效的方法。Fiddle