ES6中,可以使用箭头(=>)函数表达式的语法定义函数,这种函数表达式更适用于那些本来需要匿名函数的地方,注意它们不能用作构造函数。

基本用法

//参数、返回值单一
var f=x=>x;
//多个参数
var f=(x,y)=>x+y;
//函数体有多条语句
var f=(x,y)=>{var re=x+y;return re;};
//返回对象必须有:小括号()
var f=()=>({name:xuux,age:24});

//使用条件运算符
let max = (a, b) => a > b ? a : b;

//闭包( i=0 是默认参数)
var Add = (i=0) => {return (() => (++i) )};
var v = Add();
v();           //1
v();           //2
//因为仅有一个返回,return 及括号()也可以省略
var Add = (i=0)=> ()=> (++i);

//递归
var fact = (x) => ( x==0 ?  1 : x*fact(x-1) );
fact(5);       // 120

主要特点

  • 不绑定this;
  • 不绑定arguments。

不绑定this

  • 在ES5中:每个函数都有自己的this值,在构造函数中定义的方法,this指向调用这个方法的实例化对象;在全局作用域中调用的方法,this指向window全局对象。
  • 但是,箭头函数不会创建自己的this,它只会从自己的作用域链上一层继承this(只有在封闭的函数作用域内,才能继承其this;如果在对象字面量内定义的方法,并不能继承对象的this,因为大括号{}不能起到封闭的效果)
function Person() {
  this.age = 0;

  setInterval(function growUp() {
    this.age++;//undefined
  }, 1000);
}
var p = new Person();

这个间歇调用函数中定义的growUp回调函数,是在全局作用域下执行的,其this指向全局对象,并不是Person构造函数实例对象。
可以使用变量缓存来解决:

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

箭头函数,创建之初就绑定了作用域链继承的this,在哪里调用没有关系。

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正确地指向person对象
  }, 1000);
}
var p = new Person();

不绑定arguments

  • 不能在箭头函数中使用参数数组:arguments
  • 解决办法:剩余参数
function foo() { 
  var f = (...args) => args[0]; 
  return f(2); 
}

foo(1); 
// 2

其他特性

  • call、apply、bind方法在ES5中都是改变函数中this的指向,而箭头函数没有自己的this指针,因此,通过以上方法调用一个函数时,只能传参,忽略第一个参数。
  • 不能用作构造器,和 new一起用会抛出错误。
  • 没有prototype属性。
  • 不能用作生成器, yield 关键字通常不能在箭头函数中使用。

注意

  • 箭头函数不能作为对象的方法使用,除非将它封闭在函数作用域中;
obj = {
    data: ['John Backus', 'John Hopcroft'],
    init: function() {
        document.onclick = ev => {
            alert(this.data) // ['John Backus', 'John Hopcroft']
        }
        // 非箭头函数
        // document.onclick = function(ev) {
        //     alert(this.data) // undefined
        // }
    }
}
obj.init()
  • 不能作为构造函数;
  • 不能定义原型方法。

candyCat
172 声望17 粉丝

未来可期,不断努力~