欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript之ECMAScript6新特性之_03_箭头函数(Arrow Function)

程序员文章站 2022-05-02 22:46:41
...
一、简介
箭头函数(Arrow Function)是 ES6 (ECMAScript2015)中的新语法特性。
它是函数表达式的一种简写形式,非常适合面向过程(相对于面向对象而言)的函数式编程。
但是它也有诸多限制和“缺点”,比如:没有自己的 this 对象,没有 arguments 参数,没有 prototype 属性,不能当作构建函数使用(无法用new关键字)等等。
下面将逐一介绍。


二、语法

1、常规写法
(param1, param2, …, paramN) => { statements } 


2、参数的简写
      如果只有一个参数,则可以省略小括号。
      如果没有参数,则不能省略。
//只有一个参数
singleParam => { statements }

//没有参数
() => { statements }


3、函数体的简写
      如果只有一个 statements 表达式,则可以省略后面的 花括号。
      此时等价于把 表达式 返回。
// 函数体只有一个表达式,省略后面的花括号 { }
(param1, param2, …, paramN) => expression

// 等价于:
(param1, param2, …, paramN) => { return expression; }


// 注意:不等价于:
(param1, param2, …, paramN) => { expression }
// 此表达式表示,什么也没有返回!!!
//


      但是,如果表达式为一个 JSON 对象,则需要用小括号扩起来。
(param1, param2, …, paramN) => ({name:"John", age:18})


      本小节综合例子:
var arr = [1, 4, 9, 16];
//
var mapedArr1 = arr.map( x => x*2 );
var mapedArr2 = arr.map( x => { x*2 } );
var mapedArr3 = arr.map( x => { return x*2 } );

console.log(mapedArr1); 
//> Array [2, 8, 18, 32]
console.log(mapedArr2);
//> Array [undefined, undefined, undefined, undefined]
console.log(mapedArr3);
//> Array [2, 8, 18, 32]

      即:函数体上加花括号{},就要写 return 语句,不然什么也不返回。



4、支持多参 和 给参数设置默认值
// 多参数 ...rest
(param1, param2, ...rest) => { statements } 

// 参数默认值
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
    statements 
} 


5、支持列表结构参数解析
var arr = [1, 2];

var f = ([a, b] = arr, {x: c} = {x: a + b}) => a + b + c; 

f(); // 6

    同样,如果参数为一个 JSON 对象,则需要用小括号扩起来。
// 参数结构化解析
var f = ({length}) => length; 

// 参数结构体:{length} 等价于 {length: ""}



6、书写格式:不要换行
    不要将参数和箭头写在二行中,它们需要写在同一行中。
// 错误
var func = ()
           => 1; 
// SyntaxError: expected expression, got '=>'



下面展示一个综合示例:
//
// 下面的写法,都会将  materials 转换为 [8, 6, 7, 9] 并输出。

var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];

// 1. 常规
console.log(
    materials.map(function(material) { 
      return material.length; 
    })
);

// 2. 箭头函数
console.log(
    materials.map((material) => {
      return material.length;
    })
);

// 3. 简写的箭头函数
console.log(
    materials.map(material => material.length)
);


// 4. 简写 + 参数结构解析 的 箭头函数
console.log(
   //表示传递进的参数的结构是这样的:{ length: '' }
    materials.map(({length}) => length)
); 

//




三、箭头函数没有自己的 this 对象

在箭头函数出现之前,new 出来的函数对象,都有一个 this 属性,指向该对象本身。
然而在箭头函数中,没有 this 对象。因此不存在外层this被重写或本身this被覆盖的问题。

1、不存在 外层 this 被重写问题

【错误】常规的写法:外层 this 被 window 取代
function Person() {
    this.age = 0;
    setInterval(function growUp() { 
        if(this.age) this.age++; 
        console.log(this === window); // true
        console.log(this.age === undefined); // true
    }, 1000);
}

var p = new Person();

// 因为是调用 window 对象的 setInterval 方法,
// 所以 this 指向 window
/*
   多说一句,window 的 setInterval 方法内部实现可能是这样的:
   window.setInterval = function(func, time){
         this.invoke = func;
         //...
   }
   参数中传递的function参数被设定成为了 window 对象的一个属性。
   所以调用时,参数中的 this 指向的是 window 对象。
*/


【正确】常规写法:借用一个 that。
function Person() {
    var that = this;
    that.age = 0;

    setInterval(function growUp() {
        that.age++;
        console.log(that.age);
    }, 1000);
}
var p = new Person();


【正确】箭头函数:外层的 this 被成功传递
function Person(){
    this.age = 0;
    setInterval(() => {
        this.age++; 
        console.log(this.age);
    }, 1000);
}

var p = new Person();



2、不存在 本身this被覆盖问题
    调用 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 b = {
      base: 2
    };
    // 把 b 作为 this 对象传入,结果不起作用。
    return f.call(b, a);
  }
};

console.log(adder.add(1));         // 结果:2
console.log(adder.addThruCall(1)); // 结果:仍然是 2




四、箭头函数没有 arguments 对象 
箭头函数没有隐式的 arguments 数组对象。
// 例子一:
var arguments = [3, 2, 1];
var arr = () => arguments[0];
arr(); // 3

// 例子二:
function foo(n) {
  // 此处的 arguments 对象是 foo 函数的,
  // 不是 f 箭头函数的。因为它没有。
  var f = () => arguments[0] + n; 
  return f();
}
foo(2); // 4



五、箭头函数没有 prototype 属性 
var Foo = () => {};
console.log(Foo.prototype); // undefined



六、箭头函数不能使用 new 关键字 
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor



七、箭头函数不能单独使用 yield 关键字 

不能直接在 箭头函数 中 使用 yield 关键字(除非它被嵌套在其它函数中)。
所以 箭头函数 不能直接作为 Generator 使用。


八、在逻辑运算中,需要用小括号把 箭头函数 括起来
let callback;

callback = callback || function() {}; // ok

callback = callback || (() => {});    // ok

callback = callback || () => {};      
// SyntaxError: invalid arrow-function arguments





引用:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions







转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2409009






=