需要解释函数表达式如何作为函数声明中的参数传递

时间:2015-11-24 07:00:45

标签: javascript

将函数表达式作为参数传递

示例:

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"的结果而将参数传递给我们。

如果我在任何陈述中出错,请纠正我,我非常感谢你的帮助。

请帮助!!

谢谢你!

3 个答案:

答案 0 :(得分:1)

好吧,让我们一个接一个。

<强> 1。作为JS中的第一类对象的函数

在JS中,函数被视为第一类对象,这意味着您可以存储,将其作为参数传递,以与处理其他对象或变量相同的方式接收函数参数。

在您的情况下,匿名函数被分配给变量greeting。此函数/函数引用可以作为常规变量传递给任何其他函数。

当你将任何函数传递给另一个函数时,它会通过引用传递,为了执行它,你必须用一对括号greeting(..)调用它。

<强> 2。在函数引用中传递参数

JS函数在调用函数时不执行类型检查或传递给函数的参数数量。传递的参数在函数定义中作为参数接收时保持相同的顺序。 如 - function dummy(x, y, x){} dummy(1,2,3)如果x被调用,则会收到1 y2收到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三个形式参数的插槽(即frstlstword)及其一个局部变量(即result)。然后,评估"Joe""Bob"greeting,并将其值分配给这些广告位。 "Joe""Bob"评估这些名称的一些字符串表示,我们从Def 1知道的greeting计算结果。然后在该堆栈框架中,greet的评估从我们知道的Def 2开始。

  • 首先,word,现在被赋予greeting命名的闭包的值,将应用于frstlst的值, ,在此堆栈帧中,编译器已分配字符串"Joe""Bob"
    • 要评估greeting的值,编译器会为其2个形式参数firstlast创建第二个包含两个插槽的堆栈帧,分配"Joe"和{{ 1}}分别到那些,并开始执行"Bob"的主体。 greeting的主体连接“Joe”和“Bob”,并以“Hello”为前缀,返回字符串“Hello JoeBob”。
  • 接下来,该结果存储在名为greeting的插槽中。
  • 接下来,将分配一个新的堆栈帧来调用内置函数result(这个故事与其他调用非常相似,所以我不会详细介绍)
  • 最后,console.loggreet返回到其调用网站,该网站对该值不执行任何操作。程序然后完成执行。

答案 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