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()执行的代码会在单独的执行上下文环境中运行。因此,被调用函数的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
参考引用:
ranyifeng的es6入门 我是买了实体书然后再看电子版的
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。