我理解以下代码:
function subtract(p1, p2) { return p1 - p2; }
function calculate(p1, p2, calculator) { return calculator(p1, p2); }
var result = calculate(2, 3, subtract); //-1
但是我不明白下面的代码是如何将p1和p2识别为2和3的:
var result = calculate(2, 3, function (p1, p2) { return p1 - p2; }); //-1
4条答案
按热度按时间d5vmydt91#
更新以解决备注:
可能是我的问题不够清楚,让我换个说法,如果计算有5个参数:函数计算(p1,p2,p3,p4,计算器){返回计算器(p1,p2);有没有可能被称为:变量结果=计算(2,3,9,5,函数(p4,p3){返回p3 - p4;}); //4 not-1我真正的问题是:参数之一如何使用其他参数作为其自变量,并区分哪个参数应成为哪个自变量?
匿名函数知道使用p1和p2参数的原因是因为calculate函数定义中的参数是作为calculate函数体中的参数传递给匿名函数的。
也许一个更清楚的方法是改变匿名函数的函数定义中的参数名,这样相同的参数名就不会在匿名函数的函数定义中使用,这会造成很多混乱,在计算机科学教科书中讲授编程语言原理和抽象时,经常会故意这样做。
除了更改匿名函数中的参数名称之外,将calculate参数“calculator”更改为参数名称“fn”也有助于避免calculate和calculator之间的混淆。
函数定义:
使用匿名函数调用calculate:
我们如何知道前4个参数中的哪一个被传递给了匿名函数,哪一个没有被使用?
请参见calculate函数定义中的
return fn(p1, p2);
(位于答案的顶部),它提醒我们为什么要将p1和p2的赋值传递给匿名函数。因此,匿名函数返回3 - 2 = 1。
要进一步阅读这个概念如何创建抽象,请参阅Joel Spolsky's article - Can Your Programming Language Do This? Joel在解释JavaScript为什么如此棒方面做得很好!
9gm1akwq2#
calculate调用它的第三个参数(calculator)作为一个函数,它有自己的前两个参数p1和p2。
计算器可以通过自己版本的p1和p2访问p1和p2,这可能看起来很混乱,因为参数碰巧具有相同的名称,但它们只是通过。
在您的示例中,您传递了一个局部函数来计算,然后将使用来自calculate的前两个参数调用该函数。
qoefvg9y3#
function
是从引用名为calculator
的calculate
调用的,您可能会感到困惑,因为calculate中的arg名称与calculator中的arg名称相同。现在是计算函数,
参数如下所示,
bvjveswy4#
第三个参数是一个(匿名的)函数表达式,该表达式的结果是对一个新创建的可调用对象
Function
示例的引用。将
2
、3
和该对象引用作为参数传递给calculate
函数。calculate
的第一个和第二个参数分别命名为p1
和p2
。第三个参数命名为calculator
。因此,在calculate
中,p1
初始化为2
。用3
初始化p2
,并且用对先前创建的Function
示例的引用初始化calculator
。然后
calculate
调用引用的Function
示例,传递其p1
和p2
参数的当前值2
和3
作为第一个和第二个参数。被调用的匿名函数有自己的第一个和第二个参数
p1
和p2
,然后它们采用调用中的参数2
和3
为它们传递的值。对引用这些参数的表达式求值,并将结果返回给其调用者calculate
。calculate
然后将该值返回给 * 其 * 调用者。这种方法称为 * 回调 *。
下次请先使用调试器。