簡體   English   中英

需要解釋函數表達式如何作為函數聲明中的參數傳遞

[英]Need an explanation on how a function expression is being passed as an argument in a function declaration

將函數表達式作為參數傳遞

例:

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,是預留內存空間,當我們調用函數greet時,它為局部變量result創建內存空間。 現在變量結果被分配給word(frst,lst)這是否使它成為一個函數? 意思是word(frst,lst)一個函數表達式?

我不明白的是......

當我們用以下函數調用函數時是怎么回事?

greet("Joe","Bob",greeting);

瀏覽器能夠接受參數“Joe”和“Bob”並將它們放入word(frst,lst)然后使用參數greeting,這是一個運行函數的變量來添加它的兩個參數,當參數來自變量和函數greet有不同的名稱? 我不明白如何傳遞參數給我們"Hello Joebob"的結果。

如果我在任何陳述中出錯,請糾正我,我非常感謝你的幫助。

請幫忙!!

謝謝!

好吧,我們一個接一個。

1.作為JS中的第一類對象

在JS中,函數被視為第一類對象,這意味着您可以存儲,將其作為參數傳遞,以與您對其他對象或變量相同的方式接收函數參數。

在您的情況下,匿名函數被分配給變量greeting 此函數/函數引用可以作為常規變量傳遞給任何其他函數。

當您將任何函數傳遞給另一個函數時,它將通過引用傳遞,為了執行此操作,您必須使用一對括號greeting(..)來調用它。

2.在函數引用中傳遞參數

JS函數在調用函數時不執行類型檢查或傳遞給函數的參數數量。 傳遞的參數在函數定義中作為參數接收時保持相同的順序。 例如 - function dummy(x, y, x){}如果被調用為dummy(1,2,3)x接收為1y接收為2 ,依此類推。 如果沒有傳遞某些參數,例如dummy(1, 3) ,則JS本身將相應的參數設置為undefined 這些是由JS引擎隱式完成的。

JS函數arguments對象

JavaScript函數有一個名為arguments對象的內置對象。 參數對象包含調用(調用)函數時使用的參數數組。 對於每個函數調用,此對象都使用傳遞的參數進行設置,並且可以在函數內檢索。 例如。

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;
}

在上面的例子中,因為findMax參數是dyanmic即。 我們不確定它將調用多少個數字,最好從arguments對象而不是直接函數參數中檢索參數。

好讀 - http://bonsaiden.github.io/JavaScript-Garden/#function http://bonsaiden.github.io/JavaScript-Garden/#function.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)時,在全局上下文中評估作為函數表達式的右側以生成閉包,該數據結構包含指向已編譯函數的指針和指向全局上下文的指針(因為這是定義此功能的地方)。 此評估的結果與此頂層中的標識符greeting相關聯。

接下來執行到達(Def 2),類似地,創建閉包並將結果存儲在greet

有趣的事情始於(電話)。 為了評價greet("Joe", "Bob", greeting) ,編譯器增加了對真實在頂層用於與槽最上面的一個的頂部上的新的堆棧幀/激活記錄greet的三個形式參數(即frstlst ,和word )及其一個局部變量(即result )。 然后,評估"Joe""Bob"greeting ,並將它們的值分配給這些插槽。 "Joe""Bob"評估這些名稱的一些字符串表示,我們從Def 1知道的greeting評估為閉包。 然后在那個堆棧框架中,從我們知道的Def 2開始的greet的評估開始。

  • 首先,現在分配了由greeting命名的閉包的值的word將被應用於frstlst的值,在該堆棧幀中,編譯器已經分配了字符串"Joe""Bob"
    • 為了評估greeting的值,編譯器創建第一個堆棧幀,其firstlast為其2個形式參數提供兩個插槽,分別為這些參數分配"Joe""Bob" ,並開始執行greeting主體。 greeting的主體連接“Joe”和“Bob”並在其前面添加“Hello”,返回字符串“Hello JoeBob”。
  • 接下來,該結果存儲在名為result的槽中。
  • 接下來,將分配一個新的堆棧幀來調用內置函數console.log (這個故事與其他調用非常相似,所以我不會詳細介紹)。
  • 最后, greetundefined返回到其調用站點,該站點不對該值執行任何操作。 程序然后完成執行。

如果你要逐步分析這個(干運行),那么當你打電話greet("Joe","Bob",greeting);時會發生這種情況greet("Joe","Bob",greeting);

第1步

first| lst | word
================================================
Joe  | Bob  | function(first,last) {
     |      |     return "Hello " + first + last;
     |      |  };

第2步

var result = word(frst,lst);

這里發生的是,在第一步和第一個變量的值中調用變量字在步驟1中引用的函數。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM