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

Javascript 需要解释函数表达式如何作为函数声明中的参数传递吗,javascript,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被分配了匿名函数,该函数作为表达式传递 我知道在全局执行上下文

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

例如:

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
被分配了匿名函数,该函数作为表达式传递

我知道在全局执行上下文中,变量greeting会留出一些内存空间,而不是其中的函数

我知道函数greet会留出内存空间,当我们调用函数greet时,它会为局部变量结果创建内存空间。现在变量结果被分配给
word(frst,lst)
这是否使其成为一个函数?意义是一个函数表达式吗

我不明白的是

当我们使用以下命令调用函数时:

问候(“乔”,“鲍勃”,问候语)

浏览器是否能够将参数“Joe”和“Bob”放入
word(frst,lst)
中,然后使用参数问候语,当变量和函数问候语的参数名称不同时,该参数问候语是一个运行函数的变量,用于添加两个参数?我不明白这些参数是如何传递给我们的
“Hello Joebb”

如果我的任何陈述有误,请纠正我,我非常感谢你的帮助

请帮忙


谢谢大家!

好吧,让我们一个接一个地看吧

1。在JS中用作第一类对象

在JS中,函数被视为第一类对象,这意味着您可以像对待其他对象或变量一样存储、作为参数传递、在函数中接收参数

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

当您将任何函数传递给另一个函数时,它是通过引用传递的,为了执行此操作,您必须使用一对括号来调用它

2。函数引用中参数的传递

JS函数在调用时不执行类型检查或传递给函数的参数数。传递的参数在函数定义中作为参数接收时保持相同的顺序。 例如—
function-dummy(x,y,x){}
如果作为
dummy(1,2,3)
调用,将接收
x
as
1
y
as
2
等。如果未传递某些参数,例如
dummy(1,3)
,则JS本身会将相应的参数设置为
未定义的
。这些都是由JS引擎隐式完成的

JS函数
参数
对象

JavaScript函数有一个称为arguments对象的内置对象。 argument对象包含调用(调用)函数时使用的参数数组。每次调用函数时,都会使用传递的参数设置该对象,并且可以在函数中检索该对象。例如

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;
}
x=findMax(1123501154488);
函数findMax(){
var i;
var max=-无穷大;
对于(i=0;imax){
max=参数[i];
}
}
返回最大值;
}
在上面的示例中,由于
findMax
的参数是动态的。我们不确定将调用多少个数字,因此最好从
arguments
对象中检索参数,而不是作为直接函数参数

好书-
让我们一起来完成评估过程:

// 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)时,将在全局上下文中对右侧(函数表达式)求值以生成闭包,闭包是一种数据结构,其中包含一个指向已编译函数的指针和一个指向全局上下文的指针(因为定义此函数的地方)。此评估的结果与此顶级中的标识符
问候语
相关联

接下来执行到达(Def 2),在这里,同样地,创建一个闭包,结果存储在
greet

有趣的事情从电话开始。为了评估
greet(“Joe”,“Bob”,greeting)
,编译器在最顶层使用的堆栈框架/激活记录的顶部添加了一个新的堆栈框架/激活记录,其中包含
greet
的三个形式参数(即
frst
lst
)及其一个局部变量(即
result
). 然后,
“Joe”
“Bob”
问候语
都将被计算,并将其值分配给这些插槽<代码>“Joe”
“Bob”
计算为这些名称的一些字符串表示形式,而我们从Def 1知道的
问候语计算为闭包。然后,在该堆栈框架中,开始计算
greet
,我们从def2知道这是一个闭包

  • 首先,
    word
    ,它现在被分配了由
    greeting
    命名的闭包的值,将被应用于
    frst
    lst
    的值,在这个堆栈框架中,编译器已经分配了字符串
    “Joe”
    “Bob”
    • 为了评估
      问候语的值
      ,编译器为其两个形式参数
      first
      last
      创建了第三个堆栈框架,分别将
      “Joe”
      “Bob”
      ,并开始执行
      问候语的主体。
      问候语的主体将“Joe”和“Bob”连接起来,并在它们前面加上“Hello”,返回字符串“Hello joebb”
  • 接下来,该结果存储在名为
    result
    的插槽中
  • 接下来,一个新的堆栈帧i
    first| lst | word
    ================================================
    Joe  | Bob  | function(first,last) {
         |      |     return "Hello " + first + last;
         |      |  };
    
    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