JavaScript的獨特功能之一是'功能是對象,可以像任何對象一樣傳遞'[1]。通過將函數轉換爲JavaScript中的對象實現了什麼?
當艾希先生開始創建語言時,他爲什麼決定這麼做?與Java等語言中通常的OOP風格相比,它有什麼優勢?他有過先例,還是當時這是一個完全獨特的想法?
JavaScript的獨特功能之一是'功能是對象,可以像任何對象一樣傳遞'[1]。通過將函數轉換爲JavaScript中的對象實現了什麼?
當艾希先生開始創建語言時,他爲什麼決定這麼做?與Java等語言中通常的OOP風格相比,它有什麼優勢?他有過先例,還是當時這是一個完全獨特的想法?
當然他沒有發明它,first-class functions自60年代以來就已存在。
它給你的力量是編寫所謂的高級函數 - 將其他函數作爲參數的函數。這是函數式編程的基石。例如,Array.map
是一個將另一個函數作爲輸入的函數,允許強大的構造。
面向對象的程序設計是在後來開發的,主要集中在耦合/分離數據和行爲。這通常是以代碼輕鬆推理爲代價的(無論是在口語還是數學意義上)。許多OO語言(Java,C#)現在都增加了函數式編程(即lambda)的這些元素。
考慮使用像Java這樣的語言實現Array.map
,Array.reduce
,Array.filter
的複雜性。每次你想使用它時,你都必須創建一個特殊的匿名內部類的實例,僅僅是爲了實現算法調用所需的函數。在JavaScript中,函數只是其他所有對象的對象,所以您只需傳入一個對象,即可獲得更簡潔自然的語法。
@OrangeDog在鼻子上。我寫這個答案僅僅是爲了指出你實際上只能用函數,數組和遞歸實現所有的「經典」命令式流程控制(假設爲真== 1和假== 0):
function ifElse(cond, trueFunc, falseFunc) {
var paths = [falseFunc, trueFunc]
return paths[cond()]();
}
function whileTrue(cond, action) {
return ifElse(cond, whileTrue(cond, action), function() {});
}
function forLoop(initial, cond, increment, action) {
initial();
return whileTrue(cond, function() {
var actionValue = action();
increment();
return actionValue;
}
}
function first(array) { // or ``car``
return array[0];
}
function rest(array) { // or ``cdr``
return array.slice(1);
}
function each(array, action) {
action(first(array));
each(rest(array), action);
}
依此類推。這是Javascript的Lisp/Scheme根(它的原型繼承模型取自Self,以及來自C/Java的語法)的結果,它可以非常強大,因爲您可以輕鬆定義新的流量控制機制改變語言本身,如:
function categorizer(array, categorizer) {
var categories = {};
array.forEach(function(value, index, array) {
var category = categorizer(value, index, array);
ifElse(function() {
return categories[category] instanceof Array ? 1 : 0;
}, function() {
categories[category].push(value);
}, function() {
categories[category] = [value];
});
});
return categories;
}
這categorizer
現在可以利用一個功能,將用於定義如何陣列分割成一組中的對象標記的陣列中,可以在其他地方使用,例如:
categorize(['foo', 'bar', 'baz'], function(value) {
return value.charAt(0);
});
// Produces the following:
{
f: ['foo'],
b: ['bar', 'baz']
}
你甚至可以用純函數做算術運算! https://github.com/MatrixFrog/church_js不是我會推薦它:一般來說,速度非常慢。但至少你不會得到任何奇怪的浮點錯誤:P – MatrixFrog 2012-07-20 15:51:21
給函數fi第一類的狀態並不是新的,js是單線程的,所以爲了確保它不會阻止UI,經常有很多事情使用回調異步執行,儘管這只是一種預感,在我看來,js是一種函數式語言。 – 2012-07-18 20:50:11
我想象一下,如果函數不是對象,那麼編寫基於原型的OOP語言會遇到挑戰。 – kojiro 2012-07-18 20:53:57
想一想,這個問題意味着函數的第一類和基於類的OOP之間存在關聯。 (我認爲這就是通常的OOP風格的意義。)在基於類的語言中,函數仍然可以是一流的。 – kojiro 2012-07-18 21:02:59