整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          聊一聊JavaScript和Java、C#的“箭頭函數”

          S6 中引入了箭頭函數,這也是現在前端面試幾乎必考的內容(沒考箭頭函數,我都不好意思說自己是面試官,哈哈,開個玩笑)。有人問我,箭頭函數是個什么東西?我跟他說,就像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的原因?

          其實對于面向對象語言來說,好多都是相通的,個人感覺經常對比一下,有助于加深記憶。

          另外,如果有機會,學一門風格和自己擅長的開發語言差異比較大的,更有利于對編程語言的了解。

          ————————————————

          版權聲明:本文為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);

          總結

          希望本文能幫助大家看到箭頭函數的兩個主要好處:

          1. 語法更短
          2. 不綁定 this

          聲明一下,箭頭函數涉及的知識比本文所解釋的要多。但是本文應該已經為深入學習打下了很好的基礎。

          如果大家有關于技術的任何問題

          或者想了解更多的技術干貨私聊然后可以加朗妹兒微信喲~

          為前端工程師來說,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教程希望能給剛入門的小伙伴們帶來幫助,快動手試試吧!


          主站蜘蛛池模板: 亚洲一区二区三区久久| 色屁屁一区二区三区视频国产| 精品一区狼人国产在线| 日本不卡一区二区三区视频| 久久精品一区二区三区不卡| 精品一区二区三区在线成人 | 国产精品一区电影| 日本精品一区二区三区在线视频一| 精品一区中文字幕| 中文无码精品一区二区三区| 亚洲AV美女一区二区三区| 3D动漫精品一区二区三区| 大香伊人久久精品一区二区 | 色噜噜一区二区三区| 搜日本一区二区三区免费高清视频| 视频一区二区精品的福利| 国产精品污WWW一区二区三区 | 精品人妻无码一区二区色欲产成人| 色窝窝免费一区二区三区 | 在线播放精品一区二区啪视频| 一区二区三区在线观看免费| 亚洲线精品一区二区三区影音先锋| 国产一区二区三区影院| 精品一区二区三区AV天堂| 久久久久99人妻一区二区三区| 乱码人妻一区二区三区| 无人码一区二区三区视频| 亚洲日韩一区二区一无码| 亚洲国产成人精品久久久国产成人一区二区三区综 | 日本免费一区二区久久人人澡| 亚洲av日韩综合一区久热| 中文字幕一区在线观看| 亚洲AV成人精品日韩一区| 国产综合无码一区二区三区| 最新欧美精品一区二区三区| 精品国产香蕉伊思人在线在线亚洲一区二区| 久久综合亚洲色一区二区三区| 一区二区三区高清视频在线观看| 日本激情一区二区三区| 久久国产精品免费一区二区三区| 麻豆AV天堂一区二区香蕉|