《深入理解ES6》——箭头函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DFF1993/article/details/82865012

箭头函数

    在ES6中,箭头函数是其中最有趣的新增特性。顾名思义,箭头函数是一种使用箭头(=>)定义函数的新语法,但是它与传统的JavaScript函数有些许不同,主要集中在以下方面:

  • 没有this、super、arguments和new.target绑定 箭头函数中的this、super、arguments及new.target这些值由外围最近一层非箭头函数决定。
  • 不能通过new关键字调用  箭头函数没有[[Construct]]方法,所以不能被用作构造函数,如果通过new关键字调用箭头函数,程序会抛出错误。
  • 没有原型  由于不可以通过new关键字调用箭头函数,因而没有构建原型的需求,所以箭头函数不存在prototype这个属性。
  • 不可以改变this的绑定  函数内部的this值不可被改变,在函数生命周期内始终保持一致。
  • 不支持arguments对象  箭头函数没有arguments绑定,所以你必须通过命名参数和不定参数这两种形式访问函数的参数。
  • 不支持重复的命名参数  无论在严格还是非严格模式下,箭头函数都不支持重复的命名参数;而在传统函数的规定中,只有在严格模式下才不能有重复的命名参数。

箭头函数语法

    箭头函数的语法多变,根据实际的使用场景有多种形式。所有变种都由函数参数、箭头、函数体组成,根据使用的需要,参数和函数体可以分别采取多种不同的形式。如下,箭头函数采用了单一参数,并且只是简单的返回了参数的值:

let reflect = value => value;

//实际上相当于
let reflect = function(value){
    return value;
};

    当箭头函数只有一个参数时,可以直接写参数名,箭头紧随其后,箭头右侧的表达式被求值后便立即返回。即使没有显式的返回语句,这个箭头函数也可以返回传入的第一个参数,不需要更多的语法铺垫。

    如果要传入两个或两个以上的参数,要在参数的两侧添加一对小括号,就像这样:

let sum = (num1,num2) => num1+num2;

//实际上相当于
let sum = function(num1,num2){
    return num1+num2;
};

    如果函数没有参数,也要在声明的时候写一组没有内容的小括号,就像这样:

let getName = () => "Nicholas";

//实际上相当于
let getName = function(){
    return "Nicholas";
};

    如果你希望为函数编写由多个表达式组成的更传统的函数体,那么需要用花括号包裹函数体,并显式的定义一个返回值,如下:

let sum = (num1,num2) => {
    return num1+num2;
};

//实际上相当于
let sum = function(num1,num2){
    return num1+num2;
};

    除了arguments对象不可用以外,某种程度上你都可以将花括号里的代码视作传统函数体定义。

    如果想创建一个空函数,需要写一对没有内容的花括号,就像这样:

let doNothing = () => {};

//实际上相当于
let doNothing = function(){};

    如果想让箭头函数向外返回一个对象字面量,则需要将该字面量包裹在小括号里。如下:

let getTempItem = () => ({id:id,name:"Temp"});

//实际上相当于
let getTempItem = function(){
    return {
        id:id,
        name:"Temp"
    };
};

创建立即执行函数表达式

    传统的方式,你可以定义一个匿名函数并立即调用,自始至终不保存对该函数的引用,如下:

let person = function(name){
    return {
      getName:function(){
        return name;
      }
   };
}("Nicholas");
console.log(person.getName());//"Nicholas"

    只要将箭头函数包裹在小括号里,就可以用它实现相同的功能:

let person = ((name) => {
    return {
       getName:function(){
          return name;
       }
    };
})("Nicholas");
console.log(person.getName());//"Nicholas"

注意:小括号只包裹箭头函数的定义,没有包含("Nicholas"),这一点与正常函数有所不同,由正常函数定义的立即执行函数表达式既可以用小括号包裹函数体,也可以额外包裹函数调用的部分。

箭头函数没有this绑定

    箭头函数中没有this绑定,必须通过查找作用域链来决定其值。如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this;否则,this的值会被设置为全局对象。如下:

let pageHandler = {
    id:"123456",
    init:function(){
      document.addEventListener("click",
          event => this.doSomething(event.type),false);
    },
    doSomething:function(type){
        console.log("Handling"+type+"for"+this.id);
    }
};

    箭头函数缺少正常函数所拥有的的prototype属性,它的设计初衷是“即用即弃”,所以不能用它来定义新的类型。如果尝试通过new关键字调用一个箭头函数,会导致程序抛出错误,如下:

var myType = () => {},
    object = new myType();//错误,不可以通过new关键字调用箭头函数

箭头函数与数组

    箭头函数的语法简洁,非常适用于数组处理。举例来说,如果你想给数组排序,通常需要写一个自定义的比较器:

var result = values.sort(function(a,b){
     return a-b;
});

使用箭头函数,简化如下:

var result = values.sort((a,b) => a-b);

箭头函数没有arguments绑定

    箭头函数没有自己的arguments对象,,但它可以始终访问外围函数的arguments对象。如下:

function createArrowFunctionReturningFirstArg(){
    return () => arguments[0];
}
var arrowFunction = createArrowFunctionReturningFirstArg(5);
console.log(arrowFunction());//5

箭头函数的辨识方法

    尽管箭头函数与传统函数的语法不同,但它同样可以被识别出来,如下:

var comparator = (a,b) => a-b;
console.log(typeof comparator);//"function"
console.log(comparator instanceof Function);//true

同样,也可以在箭头函数上调用call(),apply(),及bind()方法。

var sum = (num1,num2) => num1+num2;
console.log(sum.call(null,1,2));//3
console.log(sum.apply(null,[1,2]));//3

var boundSum = sum.bind(null,1,2);
console.log(boundSum());//3

猜你喜欢

转载自blog.csdn.net/DFF1993/article/details/82865012