大家好, 我是VHotdog,热狗得小舔狗。
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。
为什么叫Arrow Function?因为它的定义用的就是一个箭头:
先康一下它的样子:
const fn = function(x) {
return x * x;
}
等价于:
const fn = x => x*x;
}
what`s F!这箭头函数看着也太舒服了!!!
可以看出x为函数参数, x*x为函数返回值!
具体用法介绍
箭头函数相当于匿名函数, 简化了函数的定义
()指的是函数参数对应的括号,可以传参,形式一样
{}指的是函数体,和函数使用一样
它有几种形式 不省去() 省去() 不省去{} 省去{}
那么什么时候省去,什么时候不省去呢?
():
当参数只有一个时,可以省去
当参数有两个及以上,和没有参数时不可省去
{}:
当函数体只有return语句时,可以省去
当函数体多条语句时,不可省去
实例
function (x){
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
//等价
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
function (x, y) {x * x + y * y}
// 等价
// 两个参数:
(x, y) => x * x + y * y
funtion () {return 3.14}
// 等价
// 无参数:
() => 3.14
// ...为ES6扩展运算符
// 扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
//console.log(...[1, 2, 3])
// 1 2 3
(x, y, ...rest) => {
var i, sum = x + y;
for (i=0; i<rest.length; i++) {
sum += rest[i];
}
return sum;
}
// 等价
function (x, y, ...rest) {
......
}
非箭头函数this指向问题
在方法中, this 指的是所有者对象。
单独的情况下,this 指的是全局对象。
在函数中,this 指的是全局对象。
在函数中,严格模式下,this 是 undefined。
在事件中,this 指的是接收事件的元素。
箭头函数this指向问题
箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。
如果你是懒人,只需要记住这一句话就好了:不管在什么情况下,箭头函数的this跟外层function的this一致,外层function的this指向谁,箭头函数的this就指向谁,如果外层不是function则指向window。
三个黄色很重要哦!!! 对下面理解有好处。我就是懒!
栗子
- 普通函数this
{
//定义一个对象
var obj = {
x:1,
show(){ // show“方法” 方法this->obj对象
//延迟500毫秒,输出x的值
setTimeout(
//匿名函数 函数this->window
function(){console.log(this.x);},
1000
);
}
};
obj.show();//打印结果:undefined
}
这里为什么打印的不是100呢?问题处在this身上,当代码执行到了setTimeout( )的时候,此时的this已经变成了window对象(setTimeout( )是window对象的方法),已经不再是obj对象了,所以我们用this.x获取的时候,获取的不是obj.x的值,而是window.x的值,再加上window上没有定义属性x,所以得到的结果就是:undefined。
- 箭头函数this
//定义一个对象
var obj = {
x:1,
show(){ // show”方法“ 方法this->obj对象
setTimeout(
//不同处:箭头函数
() => { console.log(this.x)},
1000
);
}
};
obj.show();//打印结果:1
再来个栗子
由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:
var obj = {
birth: 2000,
getAge: function () { // getAge“方法” 方法this->obj
var b = this.birth; // 2000
var fn = function () { // fn”函数“ 函数this->window
return new Date().getFullYear() - this.birth; // 指向window或undefined
};
return fn();
}
};
obj.getAge(); // 无法预知结果,因为this指向问题
现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:
var obj = {
birth: 2000,
getAge: function () { // getAge“方法” 方法this->obj
var b = this.birth; // 2000
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
obj.getAge(); // 20
注意
而且在箭头函数中,不能用call() apply()改变this指向,不生效!!!传入的第一个参数会被忽略。
var obj = {
birth: 2000,
getAge: function (year) {
var b = this.birth; // 2000
var fn = (y) => y - this.birth; // this.birth仍是2000
return fn.call({birth:2008}, year);
}
};
obj.getAge(2020); // 20
扩展:es6 扩展运算符 三个点(…)
扩展运算符( spread )是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
function add(x, y) {
return x + y;
}
var numbers = [1, 2];
add(...numbers) // 3