Javascript 数组过滤器 : getting the context right

标签 javascript functional-programming

在尝试编写一些很棒的 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 元素!

有人可以对此有所启发吗?

谢谢,

马丁

最佳答案

As you can see, I'm passing "abc" as context (which is ridiculous, ofcourse). I would expect my console to throw a lot of "abc", but instead it prints the jQuery elements!

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

三种选择:

生成数组

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

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

Updated fiddle

代理/绑定(bind)

或者,您可以使用 jQuery 的 proxy函数(或 ES5 的 Function#bind )来绑定(bind)您传递给 jQuery 的 filter 的迭代器函数,因此它会忽略 this jQuery 提供的:

$(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 明确定义 可以处理任何类似数组的东西,而不仅仅是 Array。最后一个实际上可能是最有效的方法。 Fiddle

关于Javascript 数组过滤器 : getting the context right,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11632764/

相关文章:

JavaScript MutationObserver 递归调用自身

javascript - 找出对象是否仍在内存中

functional-programming - 使用关联列表的方案中的函数表

swift - 写函数式代码时全局函数有什么优势

javascript - 在 Javascript 中引入函数式编程

python - 保留函数实现的顺序

javascript - react 映射函数未返回的无状态组件

javascript - 返回新的 Promise() 在 Node.js 中不起作用

javascript - 使用 Node js从另一个文件调用两个文件

javascript - 如何使用 Ramda 将对象映射转换为数组?