2012-06-16 18 views
4

我正在學習Javascript,並且我已經閱讀函數是第一類對象,大多數作者提到函數可以返回函數(它們是對象)並將它們作爲參數傳遞給其他函數。C#和Javascript中的函數之間的區別?

我相信還有更多的東西,所以C#中的函數和javascript中的函數有什麼區別?我有權利說函數不是對象(不具有方法,屬性等),即使使用閉包(使用lambda表達式和委託),它們看起來像JavaScript中的函數對象一樣嗎?

我覺得在C#中使用lambda表達式的區別對於剛剛學習語言的人來說有點模糊。

+4

C#甚至沒有函數*本身* - 它只有方法(和委託/ lambdas,這是方法引用)。也就是說,你可以調用代表C#模擬JavaScript匿名函數對象。 – BoltClock

+1

@BoltClock:功能與方法與程序與子程序與任何...我真的沒有看到它們之間的差異,如果不是更多... – Mehrdad

+0

@Mehrdad:是啊... :) – BoltClock

回答

1

一個最大的區別我能想到的是,在C#中的函數,變量是詞彙作用域確定,而JavaScript中,變量都是局部的除了this,這是動態作用域。

例如,在Javascript中,你可以這樣說

var foo = new Object(); 
foo.x = 0; 
var bar = function() { this.x = 2; }; // first-class function... what's "this"? 
foo.baz = bar; // Now foo has a method called 'baz', which is 'bar'. 
foo.baz(); 
alert(foo.x); // Displays 2 -- 'this' magically refers to 'foo'! 

嘗試在C#寫的。或者實際上,不要打擾 - 這不會有任何意義。

爲什麼?因爲this這裏沒有提到任何東西,詞法!它的含義動態變化,與C#不同,它的含義僅取決於封閉類,而不是調用者實際是誰。

+1

你有這個錯誤。函數中使用的變量(使用任何編程語言)可以是自由的(非本地的)或綁定的(本地的)。在詞彙範圍的語言中,當__it被定義時,函數的自由變量被解析爲函數父範圍中的變量。在動態範圍的語言中,當__it被調用___時,函數的自由變量被解析爲函數調用範圍中的變量。 'this'關鍵字不是一個自由變量。它有特殊的規則。請參閱以下[問題](http://stackoverflow.com/q/10060857/783743「動態範圍」。)。 –

+0

@AaditMShah:呃,不,我確定這是正確的......不確定你說的哪一部分是「錯誤的」,但正如我剛纔提到的,'this'是動態範圍的JS,並且其他變量是靜態範圍的。我也不知道這裏的自由與綁定變量是什麼意思,因爲我沒有看到除'this'之外的任何「自由」變量,我已經提到這個變量是動態變量。 – Mehrdad

+0

謝謝,真的很有趣...甚至沒有意識到動態範圍。 –

6

大多數作者說的是「功能是first class公民」在JavaScript中。它們分別是而不是 C#中的第一類,它們只是方法那裏,附屬於一個類。方法代表(和lambda)是爲了製作方法頭等公民的具體類。

因此,這裏的東西,盡我所能解釋,沒有告訴你回去和閱讀Crockford的「使用Javascript:好的部分」,並像飛碟雙向某人或某物:

JavaScript有少了很多零件比C#。不要把你可以在C#中直接做的事情與你可以(或不能)在Javascript中做的事情(也可以不做)進行比較。

那麼爲什麼不是所有的語言(或至少C#)都有「頭等功能」?答案通常最簡單:因爲這不是語言設計要求。然而,這是我的一個陰謀,因爲顯然他們現在已經加入了它。但是如果沒有人告訴你以你的未來語言包含它,你會嗎?

所以要記住的關鍵是:在C#函數(方法)必須附加到類。在Javascript中他們沒有。原因在於語言定義(spec)。

您可以通過以下兩種方式之一在JavaScript中創建一個新的對象:

//using object syntax 
var ob1 = { name: value, nestedFunction: function(){} }; 

//using a function 
function MyFunc(){ 
    var name = value; 
    function nestedFunction(){} 
} 
var ob2 = new MyFunc(); 

另外,我應該在對象創建語句跟進

而在第二種情況下,我們使用一個函數來聲明對象,在第一種情況下,我們只是使用文字語法來聲明它。

要做到在C#同樣的事情,我們必須創建一個新的對象爲一類:

MyClass ob1 = new MyClass(); //constructor is a member function of the class 
public class MyClass { 
    public MyClass() { 
    } 
    public void nestedFunction(){ 
    } 
} 

請注意,在JavaScript的一個我仍然有定義正在返回的方法。

好吧,我覺得今晚就夠了。

+3

我會乞求不同...'Predicate pred = i = > i%2 == 0;'對我來說看起來像一流的函數......只是這種類型不是爲你推斷的。不管怎樣,這並沒有什麼區別...... – Mehrdad

+0

它仍然是一個'Predicate '而不是一個原始函數。 C#沒有設計第一類函數的設計要求,但它們目前是該語言的一部分,但與JavaScript沒有相同的方式。無法在C#(_yet_)中進行封閉(根據維基百科你可以,但我不同意語義)。請注意,我鏈接到的wiki頁面顯示它們當前是一項功能。 – jcolebrand

+3

你不能在C#中執行閉包嗎?對不起,但是... wtf? – Mehrdad

2

Javascript函數可以創建並分配給一個變量,它們是語言中的第一類公民,並且對C#應用的語法糖具有一定的靈活性。

在C#中,當你寫的代碼

x => x * x

編譯器創建一個名爲實際方法和包裝該方法在delegate可以執行。

代表以及C#應用的語法糖給人一種非常類似於JavaScript的感覺,但它在內部做着非常不同的事情。

在JavaScript中,您可以創建一個函數並將其直接分配給一個變量並執行它,而不用將其包裝在任何其他結構中以啓用該操作。函數是JavaScript中的一等公民。

+0

在C#中,編譯器並沒有那麼做。你也需要提到的委託類型。 :-) – Mehrdad

+0

當可用時,它將使用從上下文推斷的委託類型。這可以歸結爲語法糖。 –

0

我對JS和C#的區別一些粗略的想法:

1,JS是一種解釋型語言,這意味着JS需要一個瀏覽器內置的ECMAScript的解釋工作。而C#是一種編譯語言,這意味着C#代碼將被編譯爲IL來工作。

2,JS是一種動態類型語言,這意味着您在定義時不需要指定變量的類型。而C#是靜態類型語言,這意味着您需要指定變量的確切類型。

3,OOP封裝,在JS中,很多人都說功能是一等公民。通常情況下,函數有兩種用法:a)只是一個函數來操縱一些工作b)類&構造函數,使用它可以實例化對象。而在C#中,函數是函數,它應該屬於類(或接口)。

4,OOp繼承,在JS中,我們用原型來實現繼承。而在C#中,我們嚴格使用類來實現繼承。根據我的知識,我們可以使用參數,這是一個僞數組,用來實現模擬多態的功能重載,這是一個瘀傷。而對於C#來說,多態是如此完美的體現。

6,在JS中,我們沒有GC。而C#有一個強大的GC。

也許有些想法是不正確的,歡迎提出建議。

+1

問題是關於C#和Javascript *函數*之間的語義差異 - 不是兩者作爲*語言*的區別列表。 –

0

只是爲了澄清一些混淆;

1)JavaScript確實是一種編譯語言。代碼編譯的方式就在瀏覽器執行之前,而且速度很快!這就是爲什麼有些開發人員認爲這是一種「解釋性」語言。

2)C#沒有JS意義上的函數。它有類方法。

相關問題