【问题标题】:jQuery: What is a "Value Callback"?jQuery:什么是“值回调”?
【发布时间】:2012-07-18 05:40:47
【问题描述】:

我正在学习“学习 jQuery”(第三版)。

在第 4 章:“操作 DOM”中有一节解释了称为“值回调”的东西。这对我来说是新的。

作者通过一个链接列表示例解释了这一点,其中每个的 ID 必须是唯一的

从书中:

“值回调只是一个提供的函数,而不是参数的值。然后,该函数在匹配集中的每个元素中调用一次。从函数返回的任何数据都将用作该函数的新值属性。例如,我们可以使用这种技术为每个元素生成不同的 id 值,如下所示:"

乔纳森·查弗 (2011-09-23)。学习 jQuery,第三版(第 116 页)。包出版。 Kindle 版。

jQuery(document).ready(function($){

// get all external links
   $('div.chapter a').attr({
        rel:'external',
        title:'Learn more at Wikipedia',
        id: function ( index, oldValue ) {
                return 'wikilink-' + index;
        }
    });
})

像魅力一样工作,但 id: property 的机制逃过了我的视线。

  1. 如何参数 1(索引)知道是整数?
  2. 函数如何知道递增索引?
  3. 第二个参数 (oldValue) 如何知道保存属性的旧值(修改前)?
  4. 这是一个 jQuery 构造吗?一个 JSON 的东西?这个很酷。它有效,但是......到底是什么这个“价值回调”的东西是由什么制成的?

请指教

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    1) 参数1(索引)怎么知道是整数?

    jQuery 传递一个整数。

    2) 函数如何知道递增索引?

    回调不会增加index,jQuery 方法会增加。

    3)第二个参数(oldValue)如何知道保存属性的旧值(修改前)?

    jQuery 通过它。

    执行类似于$.attr 的函数可能最能理解问题 1-3 的答案:

    Array.prototype.each = function (f) {
        var i;
        for (i=0; i < this.length; ++i) {
            f(i, this[i]);
        }
    };
    
    ['zero', 'one', 'two'].each(function (i,item) {console.log({i: item})});
    

    f 是一个回调。 each 负责遍历集合并为每个索引和项目调用 f。函数可以使用相同的代码结构:

    /* Map each item in a sequence to something else, 
     * returning a new sequence of the new values.
     */
    Array.prototype.map = function (f) {
        var i, result = [];
        for (i=0; i < this.length; ++i) {
            result[i] = f(i, this[i]);
        }
        return result;
    };
    
    ['zero', 'one', 'two'].map(function(i,item) {return item.length});
    // result: [4, 3, 3]
    
    /* Return a sequence of the items from this sequence 
     * for which 'keep' returns true.
     */
    Array.prototype.filter = function (keep) {
        var i, result = [];
        for (i=0; i < this.length; ++i) {
            if (keep(i, this[i])) {
                result.push(this[i]);
            }
        }
        return result;
    };
    
    ['zero', 'one', 'two'].filter(function(i,item) {return item.length <= 3});
    // result: ['one', 'two']
    

    mapconcatfoldl and foldr 的实现留作练习。作为另一个练习,将mapfilter 重写为each

    请注意,这些函数只是为了说明回调是如何工作的。它们可能会导致生产代码出现问题。

    4) 这是一个 jQuery 构造吗?一个 JSON 的东西?这个很酷。它有效,但是......这个“价值回调”到底是由什么组成的?

    Callbacks 是 jQuery 广泛使用的一种通用技术。它们是functional programming 的关键特性,其中函数是可以像其他数据类型一样操作的数据。因此,您拥有将函数作为参数并可以返回函数的函数。在某些情况下,callbacks 也称为“延续”,构成continuation passing style (CPS) 的基础。这对于asynchronous function calls [2] (与synchronous calls 相比,函数在计算完成之前返回)尤其重要,例如用于Ajax 请求。要了解 CPS 的一些功能,请阅读 "Use continuations to develop complex Web applications"

    另一方面,“值回调”中的“值”,因为 JS 是一种动态类型语言(类型与数据相关联,而不是变量),形式参数可以绑定到任何对象类型。然后,函数可以根据传递的内容而表现不同。有时这是通过检查参数的类型来实现的,它实际上是ad-hoc polymorphism(函数,而不是语言,必须处理调度)。但是,parametric polymorphism 或(如果失败了)duck typing 应该始终优先于检查参数类型。参数多态性是通过确保可以传递给给定函数的所有类型都支持相同的接口(方法名称、参数、前置条件、后置条件等)来实现的。例如,所有的序列类型都应该有一个length 属性并以整数为索引;只要这成立,您就可以将自己的序列类型与许多采用数组的函数一起使用。

    我不确定您所说的 JSON 是什么意思,但它可能不是通常的意思。 JSON 是一种基于 JS 对象文字语法的受限版本的数据交换格式。示例代码或引用文本的任何地方都没有涉及 JSON。

    【讨论】:

    • 更好的分解!我现在“明白了”。所以这个模式根本就不是柯里化的例子吗?
    • 这个关于柯里化的讨论对我来说还是很新的 2,它已经超出了我的想象。但是,您的细分完全回答并解释了我的问题中提出的问题。所以我把我的答案选择换成了你的。感谢您为这个答案所做的所有工作!
    【解决方案2】:

    这是一个 JQuery 构造。如果您查看源代码,您会发现 JQuery 正在检查参数以了解您传递的是值还是函数。如果它是一个函数,它的处理方式如你所见。

    【讨论】:

    • 哇。很酷。你能推荐关于这个主题的进一步阅读吗?
    • 实际上,$.attr 没有使用柯里化。柯里化是将 n 元函数(一个接受 n 参数的函数)转换为 n 一元函数,其中每个函数(最后一个除外)返回一元函数。
    猜你喜欢
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多