S6 中引入了箭頭函數,這也是現在前端面試幾乎必考的內容(沒考箭頭函數,我都不好意思說自己是面試官,哈哈,開個玩笑)。有人問我,箭頭函數是個什么東西?我跟他說,就像Java和C#中的lambda。
let func = (s)=> { console.log(s); };
func("hello world");
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");
}
var func = (string s)=> { Console.WriteLine(s); };
func("hello world");
可以看到,寫法非常類似,尤其是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語言中我們會用一個指向函數的指針。
在上一節的例子中,“hello world”是以參數的形式傳遞到方法中的,那么,是否可以直接引用外部的方法呢?
當然是可以的,改造一下上面的例子:
let str = ",圣誕快樂。";
let func = (s)=> {
console.log(s + str);
str = ",春節快樂。"
};
str = ",元旦快樂。"
func("hello world");
func("hello world");
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");
}
var str = ",圣誕快樂。";
var func = (string s) => {
Console.WriteLine(s + str );
str = ",春節快樂。";
};
str = ",元旦快樂。";
func("hello world");
func("hello world");
hello world,元旦快樂。
hello world,春節快樂。
可見,在函數執行的時候,會取當時str的值。在函數定義的時候,雖然引用了變量str,但不是此時固定了str的值。
在函數中改變了str的值,會改變外部str的值。
Java的例子中,要求str是final的才行,所以是無法對str改變的。
在JavaScript中,經常會用到類似callback的回調方法,那么箭頭函數是不是也可以呢?
let func = (s)=> {
console.log(s);
};
var showLog = function(str,action){
action(str);
}
showLog("hello world",func);
本例用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);
}
本例用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);
}
總體來說,三種語言的使用方法還是比較類似的。可能是都源于C的原因?
其實對于面向對象語言來說,好多都是相通的,個人感覺經常對比一下,有助于加深記憶。
另外,如果有機會,學一門風格和自己擅長的開發語言差異比較大的,更有利于對編程語言的了解。
————————————————
版權聲明:本文為CSDN博主「FlyLolo」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Lolo_cs_dn/article/details/122159246
周我發表了一篇為初學者介紹 this 關鍵字的博文。
(JavaScript: 為初學者介紹 new 運算符)
這篇文章中沒有涉及到的主題之一是箭頭函數。這個主題只是因為太大,沒法在那篇文章中講解,所以本文在這里做一個補充。請繼續閱讀,學習有關箭頭函數的基礎知識!
好處 #1: 更短的語法
下面我們先看一個普通的函數:
function funcName(params) {
return params + 2;
}funcName(2);// 4
上述代碼預示了創建箭頭函數的兩個原因之一:更短的語法。完全相同的函數可以被表示為只有一行代碼的箭頭函數:
var funcName = (params) => params + 2funcName(2);// 4
很棒。這個示例顯然是極端簡化的,不過但愿也能闡明我的觀點。下面我們稍微更深入地看看箭頭函數的語法:
(參數) => { 語句 }
如果沒有參數的話,我們就像下面這樣表示箭頭函數:
() => { 語句 }
當只有一個參數時,圓括號是可選的:
參數 => { 語句 }
最后,如果要返回一個表達式,就要把大括號刪掉:
參數 => 表達式// 等價于:function (參數){ return 表達式;
}
好了,現在你知道了語法,來個示例怎么樣?打開 Chrome 開發者控制臺 (Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),并鍵入如下代碼:
var double = num => num * 2
如你所見,我們正把一個箭頭函數賦值給變量 double。這個箭頭函數只有一個參數 num。因為只有一個參數,所以我們就可以省略括住參數的圓括號。因為我們想返回 num * 2 的值,所以也省略了括住要返回的表達式的大括號。下面我們調用該函數,看看其結果:
double(2);// 4double(3);// 6
好處 #2: 不綁定 this
在繼續之前,你應該很好地理解 this 關鍵字及其工作機制。
與普通函數不同,箭頭函數不需要綁定 this,而是詞法綁定 this(即,this 保持它在原始上下文中的含義)。
有個示例應該會讓這更清楚一些。在控制臺中,創建一個構造器函數,然后創建它的一個實例:
function Counter() { this.num = 0;
}var a = new Counter();
從上一篇文章你應該知道,構造器函數中 this 的值被綁定到正在新創建的對象,在本例中,就是 a 對象。這就是為什么我們輸出 a.num 會得到 0 的原因。
console.log(a.num);// 0
如果想把 a.num 的值每秒鐘增加該怎么辦呢?我們可以用 setInterval() 函數。setInterval() 是一個會在設定的毫秒數之后重復調用另一個函數的函數。下面我們把它加到 Counter 函數中:
function Counter() { this.num = 0; this.timer = setInterval(function add() { this.num++; console.log(this.num);
}, 1000);
}
上面的代碼除了加了一個變量 this.timer,并把它設置為等于 setInterval 函數外,其它的看起來與之前沒什么兩樣。每隔1000微秒(即1秒)代碼就會執行一次。this.num 會加一,然后被輸出到控制臺上。下面我們試一試,在控制臺中創建再次創建 Counter 的一個實例:
var b = new Counter();// NaN// NaN// NaN// ...
如你所見,函數會每秒都會輸出到屏幕上一次。不過這結果不是我們想要的。NaN(Not a Number)一直被輸出。那么是哪里出錯了呢?首先,運行如下代碼終止煩人的輸出:
clearInterval(b.timer);
我們再回去看看代碼。setInterval 函數不是在一個聲明過的對象上調用的,也不是用 new 關鍵字調用的(只有 Counter() 函數是)。而且最后,我們沒有用 call、bind 或 apply。setInterval 只是一個普通函數。實際上,setInterval 中 this 的值被綁定到了全局對象上!下面我們通過輸出 this 的值來驗證一下這個推測:
function Counter() { this.num = 0;this.timer = setInterval(function add() { console.log(this);
}, 1000);
}var b = new Counter();
你會看到,window 對象每秒被輸出一次。通過執行如下代碼清除掉時間間隔:
clearInterval(b.timer);
回到原始函數。它之所以輸出 NaN,是因為 this.num 引用的是 window 對象上的 num 屬性(而 window.num 是不存在的),而不是我們剛創建的 b 對象(b.num)。
那么我們該如何糾正呢?用箭頭函數!我們需要一個不綁定 this 的函數。用箭頭函數的話,this 就會一直是其上下文的原始綁定。下面把原始 Counter 函數中的 setInterval 用箭頭函數替換:
function Counter() { this.num = 0; this.timer = setInterval(() => { this.num++; console.log(this.num);
}, 1000);
}var b = new Counter();// 1// 2// 3// ...
我們會看到,控制臺開始輸出遞增的數字 - 它起作用了!Counter 構造器函數創建的原始 this 綁定被保留下來了。在 setInterval函數內,this 依然被綁定到了我們新創建的 b 對象上!
我們可以用如下代碼清除掉時間間隔:
clearInterval(b.timer);
為證明這種機制,我們再試在箭頭函數內輸出 this。我們將在 Counter 函數中創建一個名為 that 的變量。然后如果 setInterval函數中的 this 的值等于父函數 Counter 中的 this(通過 that)的值,那么就會輸出 true:
function Counter() { var that = this;this.timer = setInterval(() => { console.log(this === that);
}, 1000);
}var b = new Counter();// true// true// ...
不出所料,每次都會輸出 true!再次用如下語句清除時間間隔:
clearInterval(b.timer);
總結
希望本文能幫助大家看到箭頭函數的兩個主要好處:
聲明一下,箭頭函數涉及的知識比本文所解釋的要多。但是本文應該已經為深入學習打下了很好的基礎。
如果大家有關于技術的任何問題
或者想了解更多的技術干貨私聊然后可以加朗妹兒微信喲~
為前端工程師來說,css3的運用無疑是很廣泛的,實現的奇妙效果也是豐富多彩。它的優點遠不止于能讓你的頁面酷炫非常,一個好的css3運用能給體驗者一種莫名的心曠神怡嘿嘿嘿!
下面來看看百度是怎么使用css3的
這是百度的首頁。鏈接:http://xuanfengge.com/demo/201406/guide/
下面我們說說這是怎么實現的。
首先箭頭是一張圖片,然后效果其實就是用2個相同的DOM元素利用縮放動畫使這兩個箭頭交叉閃爍。
代碼附上:
//兩個箭頭的html
<a class="s-xguide-down trans" onclick="return false;" hidefocus=""></a>
<a class="s-xguide-down arrow-1 trans" onclick="return false;" hidefocus=""></a>
css代碼如下
圖片樣式css
css3縮放動畫
css3縮放動畫
效果引用
這個效果主要運用到了@keyframes的生成動畫,利用css3的scale對兩張圖片進行縮放、透明度的交叉,最終得到動畫的實現。
一個基礎的css3教程希望能給剛入門的小伙伴們帶來幫助,快動手試試吧!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。