ES6 中引入了箭頭函式,這也是現在前端面試幾乎必考的內容(沒考箭頭函式,我都不好意思說自己是面試官,哈哈,開個玩笑),有人問我,箭頭函式是個什么東西?我跟他說,就像Java和C#中的lambda,
1. 舉個簡單的栗子:
1.1 JavaScript:
let func = (s)=> { console.log(s); };
func("hello world");
1.2 Java:
interface Operate {
void doSomething(String str);
// void doSomething1(); 不可以有兩個方法
}
public static void main(String[] args) {
Operate func = (String s)->{ System.out.println(s);};
func.doSomething("hello world");
}
1.3 C#:
var func = (string s)=> { Console.WriteLine(s); };
func("hello world");
1.4 分析
可以看到,寫法非常類似,尤其是Js和C#, 變數func可以被當做一個函式來使用,
那么用于承接這個匿名方法的變數實際是什么?
-
JavaScript: 就是一個js中的function
-
Java: 在例子中,有點容易迷惑,明明是將lambda賦值給了一個介面型別,但最終呼叫的時候又要呼叫該介面的doSomething方法,而且這個介面只能有一個對應的方法,多了會報錯,
Java10中也提供了var關鍵字,但遺憾的是也不能被用于這樣lambda賦值的情況,
-
C#: 實際上是一個委托型別,例如:
delegate void doSomething(string str); public static void Main(string[] args) { doSomething func = (string s) => { Console.WriteLine(s); }; func("hello world"); }
? 這樣看和Java有點像了,但定義的仍然是一個方法,而不是一個介面中有一個同樣型別的方法,
- 如果在c語言中我們會用一個指向函式的指標,
2. 對函式外變數的參考
在上一節的例子中,“hello world”是以引數的形式傳遞到方法中的,那么,是否可以直接參考外部的方法呢?
當然是可以的,改造一下上面的例子:
2.1 JavaScript:
let str = ",圣誕快樂,";
let func = (s)=> {
console.log(s + str);
str = ",春節快樂,"
};
str = ",元旦快樂,"
func("hello world");
func("hello world");
2.2 Java:
interface Operate {
void doSomething(String str);
// void doSomething1(); 不可以有兩個方法
}
public static void main(String[] args) {
final String str = ",圣誕快樂";
Operate func = (String s)->{
System.out.println(s + str);
//str = ",春節快樂,";
};
//str = ",元旦快樂,"
func.doSomething("hello world");
}
2.3 C#:
var str = ",圣誕快樂,";
var func = (string s) => {
Console.WriteLine(s + str );
str = ",春節快樂,";
};
str = ",元旦快樂,";
func("hello world");
func("hello world");
2.4 分析
-
JavaScript 和C# 的結果是一樣的,輸出結果為:
hello world,元旦快樂, hello world,春節快樂,可見,在函式執行的時候,會取當時str的值,在函式定義的時候,雖然參考了變數str,但不是此時固定了str的值,
在函式中改變了str的值,會改變外部str的值,
-
Java的例子中,要求str是final的才行,所以是無法對str改變的,
3. 作為方法的引數
在JavaScript中,經常會用到類似callback的回呼方法,那么箭頭函式是不是也可以呢?
3.1 JavaScript:
let func = (s)=> {
console.log(s);
};
var showLog = function(str,action){
action(str);
}
showLog("hello world",func);
3.2 Java
本例用Consumer代替了第一節中的自定義的Operate介面,其實Consumer就是框架幫我們預定義的泛型介面,避免我們總需自定義一個介面:
public static void main(String[] args) {
Consumer<String> func = (String s)->{
System.out.println(s);
};
showLog("hello world",func);
}
public static void showLog(String str, Consumer<String> action){
action.accept(str);
}
3.3 C#
本例用Action代替了第一節中的自定義的delegate,其實Action就是框架幫我們預定義的泛型介面,避免我們總需自定義委托:
public static void Main(string[] args)
{
var func = (string s) => { Console.WriteLine(s); };
showLog("hello world", func);
}
public static void showLog(string str ,Action<string> action)
{
action(str);
}
4. 總結
總體來說,三種語言的使用方法還是比較類似的,可能是都源于C的原因?
其實對于面向物件語言來說,好多都是相通的,個人感覺經常對比一下,有助于加深記憶,
另外,如果有機會,學一門風格和自己擅長的開發語言差異比較大的,更有利于對編程語言的了解,

最后,圣誕節已經過了,祝大家元旦快樂,ps,你們要求寫年終總結了么?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/393902.html
標籤:java
上一篇:[ 資料通信面試篇 ] 數通面試題大集合(詳解),看完直懟面試官(二)
下一篇:Java(高階)——作業系統
