2011-08-11 52 views
3

這是我被卡住的代碼。當從函數返回匿名函數時,return語句中的函數是函數聲明還是函數表達式?

var bind = function(func, thisValue) { 

    return function() { 

    return func.apply(thisValue, arguments); 

    } 

} 

我一直在學習執行上下文和關閉。我的猜測是,第一個return語句中的函數是一個函數表達式,因爲它是語句的一部分。不過,我不知道如何創建一個關於func和thisValue的閉包。

如果它是一個函數表達式,那麼當調用bind時,匿名函數將不會在那裏被計算,因此不會有一個包含該函數的[[scope]]屬性設置的函數對象綁定的執行上下文。因此,匿名函數將無法通過它的[[scope]]屬性訪問func和thisValue。

因此,如果代碼的確形成閉包,那麼我的猜測是錯誤的,並且第一個return語句中的函數必須是函數聲明。或者,也許我誤解了退貨評估的時間?任何幫助,將不勝感激!

回答

1

這看起來很複雜,但其實很簡單。這個函數做的是返回一個函數,你傳遞的參數綁定到thisValue

下面是一個例子:

var bind = function(func, thisValue) { 
    return function() { 
     return func.apply(thisValue, arguments); 
    } 
} 

var x = { 
    "key": "the value" 
}; 
var y = { 
    "key": "the y value" 
}; 

function alert_key() { 
    alert(this.key); 
} 

var bound_function = bind(alert_key, x); 
bound_function(); // alerts "the value" 
var bound_function2 = bind(alert_key, y); 
bound_function2(); // alerts "the y value" 

認識到,在this.keythis勢必x,因爲它是在func.apply(thisValue, arguments)

arguments的第一個參數是很重要的是一個神奇的JavaScript變量將包含所有傳遞給函數的參數。所以func.apply(thisValue, arguments)真的只是通過所有參數,但將this上下文設置爲thisValue(或在我的示例中爲xy)。

舉例額外的參數(S):

var bind = function(func, thisValue) { 
    return function() { 
     return func.apply(thisValue, arguments); 
    } 
} 

var x = { 
    "key": "the value" 
}; 

function alert_key(another_value) { 
    alert(this.key + " " + another_value); 
} 

var bound_function = bind(alert_key, x); 
bound_function("another value"); // alerts "the value another value" 
bound_function("value y"); // alerts "the value value y" 
+0

謝謝你在這個Frits去!這並不完全是我堅持的,雖然:-)。見下文。 – aaronfalloon

+0

啊我看到了,我讀了'閉包'並跳過了其餘的問題。傻我。 – Halcyon

2

所以我做了一些挖掘在ECMAScript Language Specification和得出的結論是多數民衆贊成在返回的匿名函數是一個表達......它似乎真的現在很簡單。使用函數聲明定義函數時,標識符不是可選的,因此匿名函數不能使用函數聲明定義。匿名函數只能使用函數表達式定義,因爲對於函數表達式,標識符是可選的。

我也說這個......

如果它是一個函數表達式,然後在綁定被調用時,匿名函數不會有評估,然後,因此將不會有一個函數對象使用包含綁定執行上下文範圍的[[scope]]屬性進行設置。

我錯了。函數表達式在bind()返回時計算。因此,爲它設置了一個函數對象,並且它的所有範圍都是應該的。

我希望我已經有所作爲。如果我錯過了任何內容,請發表評論!

+0

你可以很容易地識別一個函數聲明:它是一個聲明*開始*與'function'關鍵字。其他一切都是一個函數表達式。 (好吧,不是很好,但足夠好... [進一步閱讀](http://kangax.github.com/nfe/)) – user123444555621

+0

真棒,感謝您的鏈接! – aaronfalloon