2011-12-21 43 views
1

下面的代碼將打印1如果其中一個參數被稱爲「參數」,我可以得到`arguments`對象嗎?

(function (arguments) { 
    console.log(arguments); 
}(1, 2)); 

在效果上,arguments對象已被覆蓋。是否有可能恢復函數範圍內的默認對象arguments

+6

不可以。因爲您始終完全掌握傳遞給您的參數名稱,所以不需要這樣的事情。 – Matt 2011-12-21 22:40:52

+1

@Matt:如果你將代碼注入到別人的函數中,將'arguments'定義爲一個參數來阻止你使用它? – SLaks 2011-12-21 22:44:10

+0

@SLaks那麼這個函數的作者會贏。 – Matt 2011-12-21 22:49:19

回答

2

其實,思考關於它,你可以做到這一點!

(function (arguments) { 
    (function() { 
     console.log(arguments.callee.caller.arguments); 
    })(); 
})(1, 2); 

請參閱this fiddle

+0

'callee'已棄用。 @ ruakh的答案就是你想要這樣做的方式。 – Matt 2011-12-21 23:21:11

+0

不僅'callee'不推薦使用,而且它現在以嚴格模式拋出。與具有名爲'arguments'的正式參數以及嘗試訪問函數的'arguments'屬性一樣。所以基本上,如果你關心未來的證明代碼,就不要做這些事情。 – 2011-12-21 23:27:20

+0

+1。 (儘管馬特的評論,我不認爲我的答案顯示如何做問題的問題:這個問題似乎意味着該功能是按原樣進行,我的答案需要改變功能定義。) – ruakh 2011-12-21 23:35:03

3

Matt在上面的評論中說「不」,我認爲他可能是對的;但你可以寫這樣的事情:

(function f(arguments) { 
    console.log(f.arguments); 
}(1)); 

(至少在Firefox中,我還沒有嘗試過其他的瀏覽器,但我相信這是標準的行爲)。但是如果你不願意因爲某種原因重新命名你的函數的論點,那麼我猜你可能不願意給你的函數命名呢?

(NB以上仍然是一個函數表達式,而不是一個宣言。你仍然不能引用f自身之外,這只是它不再是一個匿名函數表達式。)

+0

+1不知道函數有'arguments'的實例變量。無法想象這是線程安全的,但是哦,誰在瀏覽器JS中使用線程。 – Matt 2011-12-21 22:50:54

+0

@Matt:瀏覽器JS不支持線程(HTML5 web worker除外) – SLaks 2011-12-21 22:52:29

+0

@Matt:Re:線程安全:我真的不知道。但它似乎至少有一些特殊的範圍規則;例如'(function f(x){if(x == 1){f(2);} alert(f.arguments [0]);})(1);'alerts'2'然後'1' (至少在Firefox中),所以當內部(遞歸調用)返回時,外部調用的'arguments'必須被恢復?我不知道這是詞法還是動態。在https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/arguments上有一個MDN頁面,我確定可以回答這些問題,但目前MDN似乎正在下降。 。 。 – ruakh 2011-12-21 22:57:32

相關問題