好的,我正在尝试逐条解释:
Function.prototype.partial = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
var arg = 0;
for (var i = 0; i < args.length && arg < arguments.length; i++) {
if (args[i] === undefined) {
args[i] = arguments[arg++]; //This line is where the confusion is
}
}
return fn.apply(this, args);
};
};
第一行:
var fn = this, args = Array.prototype.slice.call(arguments);
这会将 的值this
和 的值存储arguments
在两个变量中,因为这两个值都将在以下功能块中被覆盖:
return function() {
//inside here arguments will be whatever is passed to this returned function later.
};
for 循环:
var arg = 0;
for (var i = 0; i < args.length && arg < arguments.length; i++) {
}
它基本上会遍历传递给partial
函数的所有参数,并在 if 之前退出arg >= arguments.length
。
if (args[i] === undefined) {
args[i] = arguments[arg++]; //This line is where the confusion is
}
因此,如果args
数组的参数未定义,我们将其替换为arguments
数组中的下一个参数。当每个参数都被替换时,原始函数会被合并的参数数组调用:
return fn.apply(this, args);
以下是它在实践中的工作方式:
function xy(arg1, arg2) {
console.log(arg1 + " / " + arg2);
}
var p1 = xy.partial("foo", undefined);
p1("bar") //"foo / bar"
var p2 = xy.partial(undefined, "bar");
p2("foo") //"foo / bar"
var p3 = xy.partial("foo");
p3("bar") //"foo / undefined" --> because you have to activly pass "undefined" otherwise the arguments array is too short
最后但并非最不重要的一点是,此代码如何与示例一起详细工作p1 = xy.partial("foo", undefined);
:
//lets call xy.partial("foo", undefined);
Function.prototype.partial = function() {
//fn = xy
//args = ["foo", undefined]
var fn = this, args = Array.prototype.slice.call(arguments);
//return function that is assigned to p1
//lets call p1("bar")
return function() {
//arguments = ["bar"]
var arg = 0;
//for (var i = 0; i < 2 && arg < 1; i++)
for (var i = 0; i < args.length && arg < arguments.length; i++) {
//first iteration:
//args[0] === "foo" -> nothing happend
//second iteration:
//args[1] === undefined -> args[1] = arguments[0] (= "bar"); arg++;
if (args[i] === undefined) {
args[i] = arguments[arg++]; //This line is where the confusion is
}
}
//at this point: args = ["foo", "bar"];
//now just call the function with the merged array
return fn.apply(this, args);
};
};