由於@FelixKling指出確定一個函數是否是一個聲明而不是一個表達式的唯一方法是檢查該函數的上下文。但是,在REPL(其中isExpression
函數的意圖)中沒有上下文。因此事情變得更簡單。
鍵入REPL的code
只能是一個函數聲明,如果它以關鍵字function
(在修剪開頭的空白之後)開頭的話。因此可以通過正則表達式/^\s*function\s/
進行測試。
@FelixKling指出這樣一個函數可能仍然是一個表達式,而不是一個聲明,這取決於函數的上下文(即函數是一個表達式,如果它是一個non-source element)。但傳遞給此函數的code
保證是源元素。
如果這樣的功能構建體使用條件操作符(例如function f() {} ? x : y
)或使用逗號操作者用來作爲表達(例如function f() {}, x
)然後isExpression
仍然會返回false
。然而,這樣的代碼會引起SyntaxError
。因此的isExpression
以下實現將正確地測試一些代碼是否適用於所有情況的表達式:
var isExpression = function (functionDeclaration) {
return function (code) {
if (functionDeclaration.test(code)) return false;
try {
Function("return " + code);
return true;
} catch (error) {
return false;
}
};
}(new RegExp(/^\s*function\s/));
怎麼樣'新功能(代碼+「+ 0」);'?等一下; 'new Function(code.replace(/ \ n/g,'')+「+ 0」);'...不,這也行不通。可能你必須寫一個解析器:-) – Pointy 2012-08-12 14:18:59
我不認爲你可以。函數聲明是表達式上下文中的有效表達式。因此,如果您只是在表達式上下文中評估代碼,則無法區分差異。 – 2012-08-12 14:21:51
@Pointy - 它沒有任何區別。它仍然會將__'FunctionDeclaration'__視爲__'FunctionExpression'__。 – 2012-08-12 14:22:54