es6学习笔记-箭头函数_v1.0

箭头函数使用方法

var f = v => v; //普通函数配合箭头函数写法,这里并且是传参的
//相当于
var f = function(v) {
  return v;
};

/*------------------------*/

var f = () => 5; //匿名函数配合箭头函数写法
// 等同于
var f = function () { return 5 };

/*------------------------*/
//传多个参数
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

/*------------------------*/

//传入一个id参数,然后返回一个对象
const id = 'ooo';
const getTempItem = id => ({ id: id, name: "Temp" });
//直接返回一个新对象{ id: 'ooo', name: 'Temp' }

/*------------------------*/

//传入一个对象,并且能够直接解析对象,然后获取到对象的元素
const full = ({ first, last }) => first + ' ' + last;

// 等同于
function full(person) {  //一般的写法需要借助一个对象变量来调用对象属性
  return person.first + ' ' + person.last;
}

/*------------------------*/

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);

/*------------------------*/

// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});

// 箭头函数写法
var result = values.sort((a, b) => a - b);

一个比较完整的例子:

const names = ['will', 'jack', 'peter', 'steve', 'john', 'hugo', 'mike'];

const newSet = names
    //返回[ { id: 0, name: 'will' },{ id: 1, name: 'jack' },.....],一个对象,格式为{id,name},id是原来数组的中的位置
    .map((name, index) => ({
        id: index,
        name: name
    })) 
    //对这个对象的id值进行处理(只保留偶数),并且返回一个新的对象[ { id: 0, name: 'will' }, { id: 2, name: 'peter' },....]
    .filter(man => man.id % 2 == 0)
    //将剩下的元素转换为一个包含当前元素中原名字的单元数组[ [ 'will' ], [ 'peter' ], [ 'john' ], [ 'mike' ] ]
    .map(man => [man.name])
    //不断合并相邻的两个数组,最后得到一个总数组
    .reduce((a, b) => a.concat(b));

console.log(newSet);//返回[ 'will', 'peter', 'john', 'mike' ]

相当于
const newSet = names
    .map(function (name,index) {
        return {'id':index,'name':name}
    })
    .filter(function (man) {
        return man.id % 2 == 0
    })
    .map(function (man) {
        return [man.name];
    })
    .reduce(function (a,b) {
        return a.concat(b);
    });

反引号和模板字符串相关资料

箭头函数的this

  • 箭头函数没有自己的this,也就不能用call()、apply()、bind()这些方法去改变this的指向。

  • 箭头函数的this是固定的,都指向函数定义时的作用域,主要是因为他本身并有this,所以要指向外层代码的this

  • 在箭头函数里面,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  • 因为箭头函数本身没有this,所以不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

  • 箭头函数不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

  • 箭头函数也不可以使用arguments、super、new.target.也不可以使用bind

  • 箭头函数不可以使用yield命令,因此箭头函数不能用作Generator函数。

箭头函数内部的简单逻辑:

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

// 使用babel将上述es6代码转译为ES5代码
function foo() {
  var _this = this; //可以看到这里是常用的保存当前this作用域的做法

  //因为内层代码可以访问外层代码的变量,所以可以使用到这个被保存的this
  setTimeout(function () { //因为setTimeout传入函数的话,会被全局对象调用,所以this会被指向到全局对象,可以参考setInterval
    console.log('id:', _this.id);
  }, 100);
}

关于理解箭头函数的样例:

function Timer() {
    this.s1 = 0;
    this.s2 = 0;
    // 箭头函数,this被(箭头函数)绑定在定义时所在的作用域(即Timer函数)
    setInterval(() => this.s1++, 1000);
    // 普通函数,setInterval在传入函数作为参数的时候,会以全局作用域调用
    setInterval(function () {
        this.s2++;//在全局对象下并没有s2
    }, 1000);
}

var timer = new Timer(); //new了之后,this指向就指向了新对象timer
setTimeout(() => console.log('s1: ', timer.s1), 3100);
//因为没有找到Timer的s2,所以一直没有改变他的值
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0

关于setInterval:

  • 由setInterval()执行的代码会在单独的执行上下文环境中运行。因此,被调用函数的this关键字将被设置为窗口(或全局)对象,

还有一个测试this的例子

const obj = {
    msg: 'ping',
    ping: () => this.msg
};
//因为箭头指向了全局作用域,所以返回undefined
console.log(obj.ping()); //返回undefined
//设置了一个全局作用域下的变量,因为本身箭头函数指向了全局,所以能够正常返回
var msg = 'bang!';
console.log(obj.ping()); //返回bang!

不过需要注意的是,不能在node下测试,因为node下的全局作用域并不是global,而是跟module.exports有关
Meaning of “this” in node.js modules and functions

参考引用:

  1. ranyifeng的es6入门 我是买了实体书然后再看电子版的

  2. es实战2015


线上猛如虎
2.2k 声望178 粉丝

你们都有梦想的,是吧.怀抱着梦想并且正朝着梦想努力的人,寻找着梦想的人,我想为这些人加油呐喊!