天天看點

javaScript--arrow functions(箭頭函數)解析

概述

 java現在都支援lambda表達式,js怎麼能示弱呢?來來(arrow function)箭頭函數走起,跟着大哥有肉吃,哈哈,剛開始學習javaScript,每個人都會想這小哥和java什麼關系?關系不大就是有點像。對對跑偏了,言歸正傳,箭頭函數是一般的函數的簡寫,簡寫就是圖個友善,圖友善是要付出代價,它是不能綁定它的this(本對象),arguments(參數對象),super(沒有父構造方法)或者new.target(新的目标),箭頭函數這麼多東西被砍掉了,它非常适合無方法名的函數,它不能用作構造器。

1.文法

基本文法:

//表達式(參數1,參數2,..., paramN) => {表達式}
(param1, param2, …, paramN) => { statements };
(param1, param2, …, paramN) => expression
//等同于: (param1, param2, …, paramN) => { return expression; }

// 當中有一個參數的時候可以省略括号()
(singleParam) => { statements }
singleParam => { statements }

// 對于無參的也應該加上()括号,保證格式完整性
() => { statements }
           

進階文法:

// 圓括号(json格式對象) ,不能去掉圓括号
params => ({foo: bar})

//支援rest 參數 和預設值
(param1, param2, ...rest) => { statements } 
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

//支援解構,簡單就是給個規則一一對應
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  
// 6
           

2.簡化過程:

var f = [1,2,4,5,6]
//js标準寫法
var first = f.map(function(element){
  return element*2;
});
//簡化function
var second= f.map((element)=>{
  return element*2;
});
//簡化函數體
var third = f.map((element)=>element*2);
console.log(second);//[2, 4, 8, 10, 12]
           

3.不綁定this

除了箭頭函數,每個新的函數都有他自己的this值,(相當于一個對象的構造方法),這樣上下文函數被稱為對象方法,這是非常惱火的面向對象程式設計方式。

function Person() {
  // this就是類似java的本對象,就是該類自己執行個體化的對象
  this.age = 0;

  setInterval(function growUp() {
    //growUp自己也有this對象,是以這裡this和Person的this是不一樣的
    this.age++;
  }, 1000);
}

var p = new Person();
           

在ECMAScript 3/5,被靈活指派到一個變量替代本對象,這種方式會被淘汰

function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    //that就是Person()的this對象
    that.age++;
  }, 1000);
}
           

箭頭函數發揮作用的時候到了,就是它沒有綁定自己的this。

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 就是引用person的this對象
  }, 1000);
}

var p = new Person();
           

通過Call 或者apply調用 ,它隻是通過參數,this将會被忽略

var adder = {
  base: 1,
    
  add: function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var f1 = (function(v) {
      return v+this.base;
    });
    var b = {
      base: 2
    };
            
    return f1.call(b, a);
  }
};

console.log(adder.add(1));         // 列印日志2
console.log(adder.addThruCall(1)); //f箭頭函數列印日志2 ,f1普通函數列印日志為3(普通函數綁定this,這是就是b對象,b.base=2)
           

4.不綁定arguments參數對象

//這是簡單變量名,當然不是嚴格模式下,嚴格模式下會報錯
var arguments = 42;
var arr = () => arguments;

arr(); // 42

function foo() {
  var f = (i) => arguments[0] + i; // 這個arguments[0]隐性綁定了1
  return f(2);
}

foo(1); // 3
console.log(foo(1));
           

但是如果我想要傳遞變量怎麼辦,這時候可以有rest 參數進行傳遞

function foo(i){
  var f = (...args)=>args[0]+args[1];
  return f(2,i);
}
console.log(foo(12))//結果14
           

5.箭頭函數的例子

'use strict';
//隻要{} 裡面就是鍵值對,值可以普通,也可是函數
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log(this.i, this);
  }
}
obj.b(); // prints undefined, Object {...}
obj.c(); // prints 10, Object {...}
           

6.箭頭函數不能new,因為它沒有綁定構造函數

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor ,抛出異常
           

7.箭頭函數不能使用(prototype)原生屬性

var Foo = () => {};
console.log(Foo.prototype); // undefined
           

8.對于箭頭函數的主體如果是單一,不用寫return,如果是塊語句必須用return(也就是用{}包裹的語句)

var func = x => x * x;                  
//自動會給你添加return

var func = (x, y) => { return x + y; }; 
//這個必須自己寫個return            
var f=()=>{return {bb:12}};
console.log(f());
           

9.傳回json格式的對象字元串

var func = () => { foo: 1 };               
// Calling func() returns undefined!(未定義)

var func = () => { foo: function() {} };   
// SyntaxError: function statement requires a name 文法錯誤
//因為{foo:function(){}}當做一條語句執行,而不是對象中鍵值對。
//改進一下
var func= ()=> {return ({foo:function(){}})}
           

10.不允許箭頭函數在=>位置錯行

var func = ()
           => 1; 
// SyntaxError: expected expression, got '=>'
           

11.箭頭的函數解析規則

let callback;

callback = callback || function() {}; // 這樣寫沒毛病

callback = callback || () => {};      
// SyntaxError: invalid arrow-function arguments   報錯 ()=>{}不是一個整體

callback = callback || (() => {});    // 這樣寫也沒問題
           

12.更多例子:

// empty傳回undefined
let empty = () => {};

(() => 'foobar')(); 
// Returns "foobar"
// (this is an Immediately Invoked Function Expression 
// see 'IIFE' in glossary)

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Easy array filtering, mapping, ...

var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce((a, b) => a + b);  
// 66
//過濾偶數
var even = arr.filter(v => v % 2 == 0); 
// [6, 0, 18]

var double = arr.map(v => v * 2);       
// [10, 12, 26, 0, 2, 36, 46]

// More concise promise chains
promise.then(a => {
  // ...
}).then(b => {
   // ...
});

// Parameterless arrow functions that are visually easier to parse
setTimeout( () => {
  console.log('I happen sooner');
  setTimeout( () => {
    // deeper code
    console.log('I happen later');
  }, 1);
}, 1);
           

繼續閱讀