2011-09-03 106 views
64

我得到了javascript中的一段代碼,我只是不明白:JavaScript的嵌套函數

function dmy(d) { 
    function pad2(n) { 
     return (n < 10) ? '0' + n : n; 
    } 

    return pad2(d.getUTCDate()) + '/' + 
     pad2(d.getUTCMonth() + 1) + '/' + 
     d.getUTCFullYear(); 
} 

function outerFunc(base) { 
    var punc = "!"; 

    //inner function 
    function returnString(ext) { 
     return base + ext + punc; 
    } 

    return returnString; 
} 

怎麼能功能的其他函數中定義?我們可以從my()函數之外調用pad2()嗎?

請說明一下。除非我錯了感謝

+8

功能可以在函數中被創建。這是完全有效的。 – 0x499602D2

回答

109

函數是JavaScript中的另一種類型的變量(當然有一些細微差別)。在另一個函數內創建一個函數會改變函數的作用域,就像改變一個變量的作用域一樣。這對於使用閉包來減少總體全局名稱空間污染尤爲重要。除非它們已經連接到一個對象,它是函數外部接近

另一個功能中定義的功能將不會是函數外部接近:

function foo(doBar) 
{ 
    function bar() 
    { 
    console.log('bar'); 
    } 

    function baz() 
    { 
    console.log('baz'); 
    } 

    window.baz = baz; 
    if (doBar) bar(); 
} 

在這個例子中,功能巴茲將可用在foo函數運行後使用,因爲它被覆蓋window.baz。除了foo函數中包含的示波器以外,任何其他上下文都不能使用該條形函數。

作爲不同的例子:

function Fizz(qux) 
{ 
    this.buzz = function(){ 
    console.log(qux); 
    }; 
} 

Fizz功能被設計成一個構造函數,以便在運行時,它分配一個buzz函數到新創建的對象。

+0

什麼是window.baz = baz?爲什麼這條線路可用? –

+0

@ZiyangZhang,後段代碼塊有解釋,有沒有一個特定的部分不清楚? – zzzzBov

+0

速度和記憶效率都很低..請參閱下面的答案 – kofifus

12
function x() {} 

等於(或非常相似)

var x = function() {} 

所以沒有什麼好笑的事情發生。

+5

第一種語法將被移至文檔的開頭。 所以有可能在函數初始化之前調用函數'x'。 – Tom

+5

第一個語法也會給你帶來命名函數更好的棧跟蹤,第二個語法會給你頭痛 – TheZ

7

函數實例化被允許在函數的內部和外部。在這些函數內部,就像變量一樣,嵌套函數是局部的,因此不能從外部範圍獲得。

function foo() { 
    function bar() { 
     return 1; 
    } 
    return bar(); 
} 

foo操縱bar內本身。 bar除非在外部範圍內定義,否則不能從外部範圍觸及。

所以這是行不通的:

function foo() { 
    function bar() { 
     return 1; 
    } 
} 

bar(); // throws error: bar is not defined 
3

這是在Javascript(和許多語言)完全正常的有內部函數的函數。

花時間學習語言,不要在與已知類似的基礎上使用它。我建議觀看道格拉斯克羅克福德關於Javascript的YUI系列演講,特別關注Act III: Function the Ultimate(鏈接到視頻下載,幻燈片和成績單)

4

當您在一個函數中聲明一個函數時,內部函數僅在聲明範圍內可用,或者在您的情況下,只能在dmy範圍內調用pad2

所有現有dmy的變量是pad2可見,但它並沒有發生周圍的其他方式:d