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']
mapconcat、foldl and foldr 的实现留作练习。作为另一个练习,将map 和filter 重写为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。