2015-11-24 41 views
3

一個參數傳遞函數表達式作爲參數傳遞的說明需要有關如何的函數表達式被作爲在函數聲明

實施例:

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)這是否使它成爲函數?意思是word(frst,lst)函數表達式?

我不明白的是...

它是如何,當我們調用該函數:

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

瀏覽器能夠採取的說法「喬」和「Bob」並將它們放到word(frst,lst)中,然後使用參數greeting,這是一個變量,它運行一個函數來添加它的兩個參數,當變量和函數greet中的參數具有不同的名稱時?我不明白這些論據是如何傳遞給我們的,給我們"Hello Joebob"的結果。

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

請幫忙!!

謝謝!

+2

所有這些都只是被某個存儲在內存中的函數對象的引用。所以'word'是指向內存中相同函數的引用的副本。 – zerkms

回答

1

好吧,讓我們一個接一個。

1.功能,如JS第一類對象

在JS,功能分別作爲第一類對象處理,這意味着你可以存儲,它作爲參數傳遞,接收功能參數在你做同樣的方式與其他對象或變量。

就你而言,匿名函數被分配給變量greeting。該函數/函數引用可以作爲正常變量傳遞給任何其他函數。

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

2.傳遞引用被調用時

JS函數不執行類型檢查或傳遞給函數的參數的個數。當它們作爲函數定義中的參數被接收時,傳遞的參數保持相同的順序。 如 - function dummy(x, y, x){}如果援引爲dummy(1,2,3)將收到x1y作爲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 ie。我們不確定將調用多少個數字,最好從arguments對象中檢索參數,而不是直接函數參數。

良好讀取 - http://bonsaiden.github.io/JavaScript-Garden/#function http://bonsaiden.github.io/JavaScript-Garden/#function.arguments

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,lstword)及其一個局部變量(即result)。然後,"Joe""Bob",和greeting都評估和它們的值被分配到那些插槽。 "Joe""Bob"評估這些名字的一些字符串表示,和greeting我們知道,從防守1計算爲一個封閉。然後在那個堆棧框架中,我們知道從Def 2開始的greet的評估開始。

  • 首先,word,其現在被指定由greeting命名封閉件的值,將要被施加到的frstlst的值,其在此堆棧幀編譯器分配了字符串"Joe""Bob"
    • 爲了評價greeting的值,編譯器爲其2個形式參數firstlast,分配"Joe""Bob"那些分別創建具有兩個狹槽的第三堆棧幀,並開始執行的greeting身體。 greeting的主體連接了「Joe」和「Bob」,並將它們預先設置爲「Hello」,並返回字符串「Hello JoeBob」。
  • 接着,該結果被存儲在稱爲result插槽。
  • 接下來,將分配一個新的堆棧框架來調用內置函數console.log(這個故事與其他調用非常相似,所以我不會詳細討論)。
  • 最後,greetundefined返回給其呼叫站點,該呼叫站點對該值不做任何處理。程序然後完成執行。
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); 

發生了什麼h在步驟-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

相關問題