整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          JavaScript箭頭函數(shù)

          JavaScript中,函數(shù)可以用箭頭“=>”來定義,稱之為箭頭函數(shù),有時候也稱之為lambda表達式(lambda Expression)。箭頭函數(shù)是一個匿名函數(shù),其語法比函數(shù)表達式更簡潔,相比函數(shù)表達式,箭頭函數(shù)沒有自己的 this、arguments、super或new.target。箭頭函數(shù)更適用于那些需要匿名函數(shù)的地方,并且它不能用作構造函數(shù)。

          1.基礎語法

          //多個參數(shù)
          (param1, param2, …, paramN) => { statements }
          //只有一個參數(shù)
          (param) => { statements }
          //當只有一個參數(shù)時,圓括號可以省略
          param => { statements }
          //函數(shù)體只有一條 return語句
          (param1, param2, …, paramN) => { return expression; }
          //當函數(shù)體只有一條 return語句時,可以省略 return關鍵字和函數(shù)體的花括號
          (param1, param2, …, paramN) => expression
          //沒有參數(shù)的函數(shù)必須寫一對圓括號
          () => { statements }

          2.高級語法

          //加圓括號的函數(shù)體返回對象字面量表達式
          params => ({foo: bar})
          //支持剩余參數(shù)和默認參數(shù)
          (param1, param2, …rest) => { statements }
          (param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
              statements
          }
          //支持參數(shù)列表解構
          let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
          f(); // 6

          3.箭頭函數(shù)不綁定 this

          在普通函數(shù)中,this總是指向調用它的對象,如果是構造函數(shù),this指向創(chuàng)建的對象實例。箭頭函數(shù)本身沒有 this,但是它在聲明時可以捕獲其所在上下文的 this。例如:

          var msg = "hello";
          let func = () => {
              console.log(this.msg);
          };
          func();//hello

          在上面的代碼中,箭頭函數(shù)在全局作用域聲明,所以它捕獲全局作用域中的 this,this.msg即得到全局作用域中的 msg的值"hello"。

          4.箭頭函數(shù)不會暴露arguments對象

          普通函數(shù)調用后都具有一個 arguments 對象存儲實際傳遞的參數(shù),但是箭頭函數(shù)沒有這個對象。在大多數(shù)情況下,可以使用rest參數(shù)來代替arguments對象。例如:

          心箭頭

          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="UTF-8">
          <title>實心箭頭</title>
          <style>
          .con{
              width: 300px;
              height: 300px;
              border: 1px solid #ccc;
              margin: 50px auto;
              background-color:#ccc;
          }
          .arrow-top{
              border-bottom: 10px solid #fff;
              border-right: 10px solid #fff;
              border-left: 10px solid #fff;
              border-top: 10px solid #ccc;
              width: 0px;
              height: 0px;
              position: relative;
              top:-40px;
              left:100px;
          }
          
          .arrow-bottom{
              border-bottom: 10px solid #fff;
              border-right: 10px solid #fff;
              border-left: 10px solid #fff;
              border-top: 10px solid #ccc;
              width: 0px;
              height: 0px;
              position: relative;
              top:-40px;
              left:100px;
          }
          </style>
          </head>
          <body>
          <div class="con">
          <div class="arrow-top"> </div>
          </div>
          </body>
          </html>



          非實心箭頭

          S6中,除了let和const新特性,箭頭函數(shù)是使用頻率最高的新特性了。如果你曾經了解如日中天的JavaScript衍生語言CoffeeScript, 就會清楚此特性并非ES6獨創(chuàng)。箭頭函數(shù)顧名思義是使用箭頭(=>)定義的函數(shù),屬于匿名函數(shù)一類。

          今天的文章內容將會從以下幾個方面,介紹箭頭函數(shù):

          • 使用語法
          • this穿透
          • 箭頭函數(shù)和傳統(tǒng)函數(shù)的區(qū)別

          本篇文章閱讀時間預計8分鐘

          使用語法

          箭頭函數(shù)有四種使用語法

          1、單一參數(shù)的單行箭頭函數(shù)

          如下段代碼所示,很簡單:

          const fn= foo =>`${foo} world`;
          

          這是箭頭函數(shù)最簡潔的形式,常用于用作簡單的處理函數(shù),如過濾。如下段代碼所示:

          let array=['a','bc','def','ghij'];
          array=array.filter(item=>item.length>=2);
          

          2、多參數(shù)的單行箭頭函數(shù) 語法也很簡單,如下段代碼所示:

          const fn=(foo,bar) => foo+bar
          

          在實際開發(fā)中,函數(shù)的參數(shù)不會只有一個,在箭頭函數(shù)中,多參數(shù)的語法跟普通函數(shù)一樣,用括號包裹參數(shù)項。我們經常處理函數(shù),如排序,示例代碼如下:

          let array=['a','bc','def','ghij'];
          array=array.sort((a,b) => a.length < b.length);
          

          3、多行箭頭函數(shù) 單一參數(shù),如下段代碼所示:

          foo => {
           return `${foo} world`;
          }
          

          多參數(shù),如下段代碼所示:

          (foo,bar) => {
           return foo+bar;
          }
          

          4、無參數(shù)箭頭函數(shù)

          如果一個箭頭函數(shù)無參數(shù)傳入,則需要用一對空的括號來表示空的參數(shù)列表。

          const greet = () => 'Hello World'
          

          以上都是被支持的箭頭函數(shù)的表達方式,其最大的好處就是簡單明了,省略了function關鍵字,而使用 => 代替。相對于傳統(tǒng)的function函數(shù),箭頭函數(shù)在簡單的函數(shù)使用中更為簡潔直觀。

          書寫箭頭的函數(shù)過程中,我們應該注意以下幾點:

          1、使用單行箭頭函數(shù)時,應避免換行

          錯誤的用法,如下段代碼所示:

          const fn=x
          => x*2 //SyntaxError
          

          正確的寫法,如下:

          const fn= x => x*2 //ok
          

          2、參數(shù)列別的右括弧、箭頭應在一行

          錯誤的用法,如下段代碼所示:

          const fn = (x,y) //SyntaxError
          => {
           return x*y;
          }
          

          下段代碼書寫是正確的:

          const fn= (x,y) => { //ok
           return x*y
          }
          const fn= (x,
           y) => { //ok
           return x*y 
          }
          

          3、單行箭頭函數(shù)返回只能包含一條語句

          錯誤的書寫,如下段代碼所示:

          const fn1= x => x=x*2; return x+2; //SyntaxError
          

          正確的書寫,如下段代碼所示:

          const fn2= x => {
           x=x*2;
           return x+2;
          } //ok
          

          4、如果單行箭頭返回一個對象,請用圓括號包裹

          錯誤的書寫,如下段代碼所示,解析引擎會將其解析成一個多行箭頭函數(shù):

          const ids=[1,2,3];
          const users=ids.map(id=>{id:id});
          //wrong:[ undefined, undefined, undefined ]
          

          正確的書寫,如下段代碼所示:

          const ids=[1,2,3];
          const users=ids.map(id=>({id:id}));
          //Correct:[ { id: 1 }, { id: 2 }, { id: 3 } ]
          

          箭頭函數(shù)十分簡潔,特別適合單行回調函數(shù)的定義,比如我們有以下需求:

          我們有一個這樣的名字數(shù)組names,['Will','Jack','Peter','Steve','John','Hugo','Mike'],輸出序號為偶數(shù)的名字[ 'Will', 'Peter', 'John', 'Mike' ],我們如何使用箭頭函數(shù)在一行語句完成呢,如下段代碼所示:

          const names=['Will','Jack','Peter','Steve','John','Hugo','Mike'];
          const newSet=names
          .map((name,index)=>({
           id:index,
           name:name
          }))
          .filter(man => man.id %2 ==0)
          .map(man => [man.name])
          .reduce((a,b) => a.concat(b))
          

          this穿透

          事實上,箭頭函數(shù)不僅書寫簡潔,還有一個神奇的功能,就是將函數(shù)內部的this延伸上一層作用域中(綁定最近的非箭頭函數(shù)的上下文),及上一層的上下文會穿透到內層的箭頭函數(shù)中,讓我們先看一段實際的例子,如下段所示:

          var Widget={
           // A
           init:function () {
           // B
           document.addEventListener("click", function (event){
           //C
           this.doSomething(event.type);
           }, false);
           },
           doSomething:function (type) {
           console.log("Handling"+ type+"event");
           }
          };
          Widget.init();
          

          這段代碼會如何輸出呢,想必大家都猜到了吧,輸出undefined,為什么呢?我們在B位置內聲明了函數(shù)(C區(qū)域),this關鍵詞的指向B區(qū)域的函數(shù),由于B區(qū)域內沒有doSomething函數(shù)聲明,因此輸出undefined,ES6之前我們如何修正此問題呢?

          我們可以使用bind方法改變this指向A區(qū)域Widget對象,示例代碼如下:

          var Widget={
           // A
           init:function () {
           // B
           document.addEventListener("click", (function (event) {
           //C
           this.doSomething(event.type);
           }).bind(this), false);
           },
           doSomething:function (type) {
           console.log("Handling"+ type+"event");
           }
          };
          Widget.init();
          

          下面這種方法是我們最常用的方法,我們在B區(qū)域聲明了that變量,并將其this賦值,確保c區(qū)域this的指向至Widget對象:

          var Widget={
           // A
           init:function () {
           // B
           var that=this;
           document.addEventListener("click", function (event) {
           //C
           that.doSomething(event.type);
           console.log(that);
           }, false);
           },
           doSomething:function (type) {
           console.log("Handling"+ type+"event");
           }
          };
          Widget.init();
          

          有了箭頭函數(shù),我們可以使用箭頭函數(shù)的this穿透功能,將this的作用域延伸至上一層B區(qū)域函數(shù),綁定最近的非箭頭函數(shù)的上下文,如下段代碼所示:

          var Widget={
          //A
           init:function () {
           //B
           document.addEventListener("click", (event) => {
           //C
           this.doSomething(event.type);
           }, false);
           },
           doSomething:function (type) {
           console.log("Handling"+ type+"event");
           }
          };
          Widget.init();
          

          箭頭函數(shù)是不是更簡單,代碼更清晰呢。

          還有一個情況需要注意,箭頭函數(shù)對上下文的綁定是強制的,無法通過call或aplly進行改變,如下段代碼所示:

          function widget() {
           this.id=123;
           this.log=()=>{
           console.log(this)
           console.log('widget log',this.id);
           }
          }
          var pseudoWidget={
           id:456
          };
          new widget().log.call(pseudoWidget);//123
          

          上述代碼會如何輸出呢,由于箭頭函數(shù)對上下文的綁定是強制的,因此this指向不會指向pseudoWidget對象,因此輸出123。

          箭頭函數(shù)和傳統(tǒng)函數(shù)的區(qū)別

          1、箭頭函數(shù)作為匿名函數(shù),是不能作為構造函數(shù)的,不能使用new

          如下段代碼所示,我們使用new方法,會提示如下信息:

          const B =()=>({wechat:"前端達人"});
          let b = new B(); //TypeError: B is not a constructor
          

          2、箭頭函數(shù)不綁定arguments,可以使用剩余參數(shù)(rest)解決

          function A(a){
           console.log(arguments); //[object Arguments] {0: 1}
          }
          var B = (b)=>{
           console.log(arguments); //ReferenceError: arguments is not defined
          }
          var C = (...c)=>{ //...c即為rest參數(shù)
           console.log(c); //[3]
          }
          A(1);
          B(2);
          C(3);
          

          3、箭頭函數(shù)this指向具備穿透特性,會捕獲其所在上下文的this值

          4、箭頭函數(shù)沒有原型屬性

          var a = ()=>{
           return '前端達人';
          }
          function b(){
           return '前端達人';
          }
          console.log(a.prototype);//undefined
          console.log(b.prototype);//object{...}
          

          5、箭頭函數(shù)不能當做Generator函數(shù),不能使用yield關鍵字

          6、箭頭函數(shù)對上下文的綁定是強制的,無法通過call或aplly進行改變

          小節(jié)

          今天的內容就介紹到這里,我們可以看出使用箭頭函能減少代碼量,更加簡介易讀。在使用箭頭函數(shù)時,我們一定要理解箭頭函數(shù)和傳統(tǒng)函數(shù)的區(qū)別,如果函數(shù)功能簡單,只是簡單的邏輯處理,盡量使用箭頭函數(shù)。

          更多精彩內容,請微信關注"前端達人”公眾號


          主站蜘蛛池模板: 亚洲国产美女福利直播秀一区二区| 国产精品视频免费一区二区三区 | 色天使亚洲综合一区二区| 午夜爽爽性刺激一区二区视频| 国产免费一区二区三区在线观看| 男人的天堂av亚洲一区2区| 久久国产精品一区免费下载| 一区二区三区四区电影视频在线观看| 日本一区二区三区爆乳| 色狠狠AV一区二区三区| 亚洲AV日韩AV天堂一区二区三区 | 视频在线一区二区三区| 韩国精品一区视频在线播放| 亚洲欧洲无码一区二区三区| 亚洲视频一区二区三区四区| 少妇精品无码一区二区三区| 亚洲一区二区成人| 亚洲一区二区三区四区在线观看 | 一区二区三区在线|欧| 国产免费一区二区三区在线观看| 免费观看一区二区三区| 精品国产一区二区三区免费| 日韩一区二区三区无码影院| 人妻无码视频一区二区三区 | 天天爽夜夜爽人人爽一区二区| 国产激情一区二区三区在线观看| 国产综合视频在线观看一区 | 精品久久久久中文字幕一区| 久久无码人妻精品一区二区三区| 日本一区视频在线播放| 久久国产三级无码一区二区| 中文字幕aⅴ人妻一区二区| 国产亚洲一区二区三区在线| 乱精品一区字幕二区| 在线观看日本亚洲一区| 在线日韩麻豆一区| 日韩AV无码一区二区三区不卡毛片| 久久青草国产精品一区| 亚洲综合av一区二区三区| 后入内射国产一区二区| 夜夜添无码一区二区三区|