将函数表达式作为参数传递
示例:
var greeting = function(first,last) {
return "Hello " + first + last;
};
function greet(frst,lst,word) {
var result = word(frst,lst);
console.log(result);
}
greet("Joe","Bob",greeting);
我理解var greeting
被赋予匿名函数,并且此函数作为表达式传递。
据我所知,在全局执行上下文中,变量问候语是留出一些内存空间,而不是内部函数。
我知道函数问候,是预留内存空间,当我们调用函数greet时,它会为局部变量result创建内存空间。现在变量结果被分配给word(frst,lst)
这是否使它成为一个函数?意思是word(frst,lst)
一个函数表达式?
我不明白的是......
当我们用:
调用函数时是怎么回事? greet("Joe","Bob",greeting);
浏览器能够接受参数" Joe"和#34; Bob"并将它们放入word(frst,lst)
然后使用参数greeting,它是一个运行函数的变量,用于添加它的两个参数,当变量和函数greet的参数有不同的名称时?我不明白为了给我们"Hello Joebob"
的结果而将参数传递给我们。
如果我在任何陈述中出错,请纠正我,我非常感谢你的帮助。
请帮助!!
谢谢你!答案 0 :(得分:1)
好吧,让我们一个接一个。
<强> 1。作为JS中的第一类对象的函数
在JS中,函数被视为第一类对象,这意味着您可以存储,将其作为参数传递,以与处理其他对象或变量相同的方式接收函数参数。
在您的情况下,匿名函数被分配给变量greeting
。此函数/函数引用可以作为常规变量传递给任何其他函数。
当你将任何函数传递给另一个函数时,它会通过引用传递,为了执行它,你必须用一对括号greeting(..)
调用它。
<强> 2。在函数引用中传递参数
JS函数在调用函数时不执行类型检查或传递给函数的参数数量。传递的参数在函数定义中作为参数接收时保持相同的顺序。
如 -
function dummy(x, y, x){}
dummy(1,2,3)
如果x
被调用,则会收到1
y
,2
收到dummy(1, 3)
,依此类推。如果没有传递某些参数,例如undefined
,则JS本身将相应的参数设置为arguments
。这些是由JS引擎隐式完成的。
JS函数x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i;
var max = -Infinity;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
对象
JavaScript函数有一个名为arguments对象的内置对象。 参数对象包含调用(调用)函数时使用的参数数组。对于每个函数调用,此对象都使用传递的参数进行设置,并且可以在函数内检索。例如。
findMax
在上面的例子中,因为arguments
的参数是dyanmic ie。我们不确定它将调用多少个数字,最好从UIPageViewController
对象而不是直接函数参数中检索参数。
好读 - http://bonsaiden.github.io/JavaScript-Garden/#function http://bonsaiden.github.io/JavaScript-Garden/#function.arguments
答案 1 :(得分:1)
让我们一起完成评估过程:
// Def 1
var greeting = function(first, last) {
return "Hello " + first + last;
};
// Def 2
function greet(frst, lst, word) {
var result = word(frst, lst);
console.log(result);
}
// Call
greet("Joe", "Bob", greeting);
当执行到达(Def 1)时,在全局上下文中评估作为函数表达式的右侧以生成闭包,该数据结构包含指向已编译函数的指针和指向该函数的指针。全局上下文(因为这是定义此函数的位置)。此评估的结果与此顶层中的标识符greeting
相关联。
接下来执行到达(Def 2),类似地,创建一个闭包,结果存储在greet
。
有趣的事情始于(呼叫)。为了评估greet("Joe", "Bob", greeting)
,编译器在顶层使用的最顶层上添加一个新的堆栈帧/激活记录,其中包含greet
三个形式参数的插槽(即frst
,lst
和word
)及其一个局部变量(即result
)。然后,评估"Joe"
,"Bob"
和greeting
,并将其值分配给这些广告位。 "Joe"
和"Bob"
评估这些名称的一些字符串表示,我们从Def 1知道的greeting
计算结果。然后在该堆栈框架中,greet
的评估从我们知道的Def 2开始。
word
,现在被赋予greeting
命名的闭包的值,将应用于frst
和lst
的值, ,在此堆栈帧中,编译器已分配字符串"Joe"
和"Bob"
。
greeting
的值,编译器会为其2个形式参数first
和last
创建第二个包含两个插槽的堆栈帧,分配"Joe"
和{{ 1}}分别到那些,并开始执行"Bob"
的主体。 greeting
的主体连接“Joe”和“Bob”,并以“Hello”为前缀,返回字符串“Hello JoeBob”。greeting
的插槽中。result
(这个故事与其他调用非常相似,所以我不会详细介绍) console.log
将greet
返回到其调用网站,该网站对该值不执行任何操作。程序然后完成执行。答案 2 :(得分:1)
如果您要逐步分析(干运行),那么当您拨打greet("Joe","Bob",greeting);
时会发生这种情况
<强> STEP-1 强>
first| lst | word
================================================
Joe | Bob | function(first,last) {
| | return "Hello " + first + last;
| | };
<强> STEP-2 强>
var result = word(frst,lst);
这里发生的事情是,使用第一个和第一个变量的值调用第一步中变量字引用的函数。
ie. word('Joe', 'Bob');
如此干燥运行我们得到的这个功能
var greeting = function(first,last) {
return "Hello " + first + last;
};
first | last | return value = ("Hello " + first + last) | result
================================================================
Joe | Bob | Hello JoeBob | Hello JoeBob
所以,console.log(result);
= Hello JoeBob