天天看点

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);
           

继续阅读