ES6允许使用箭头 => 定义函数
let v = 100 // 箭头函数 let f = a => v; // 等同于 let f2 = function (a){ return v } // 等同于 let f3 = (a) => { return v } console.log(f()); // 100 console.log(f2()); // 100 console.log(f3()); // 100
箭头函数中,使用圆括号()代表参数的部分
// 无参数 let a1 = () => 5; // 等同于 let a2 = function () {return 5
// 有参数 let a3 = (num1,num2) => num1 + num2 // 等同于 let a4 = function (num1,num2) { return num1 + num2}
如果箭头函数中的代码块为一句话,可以省略大括号。
如果箭头函数中的代码块多于一句,需要使用大括号括起来,使用return可以返回数据。
大括号被解释为代码块,如果箭头函数返回的是一个对象,就必须在对象外面加上括号,否则报错
// 错误写法 let b1 = id => { id : id , name : '东方不败'} // 报错
// 正确写法 let id = 1 let b2 = id => ({id,name:'东方不败'}) console.log(b2()); // id : undefined ,name :'东方不败'
上面这个代码块中,箭头函数参数为id,调用b2函数时未传参数,所以id为undefined,参数部分其实是定义了一个let id;该id并没有赋值,所以是undefined;
在普通函数中,函数没有参数且函数内部没有定义变量,内部的变量会向上寻找变量,所以这里内部return的id指向的是外层全局变量id
let id = 1 function b3(){ return {id,name:'东方求败'} } console.log(b3()); // id : 1 ,name :'东方不败'
如果函数有参数,但是调用函数时未传参,那么该参数就是undefined;
// 这里有一个参数,但是调用的时候没有传参,所以id为undefined function b4(id){ return {id,name:'东方求败'} } console.log(b4()); // id : undefined ,name :'东方不败'
函数参数部分其实是有一个作用域的,参数部分的id其实是定义了一个let id,下面这个例子就能说明:
// 报错 let id = 1 function b5(id = id){ return {id,name:'东方求败'} } b5()
这里的id其实就是let id = id ,id为一个未声明的变量,赋值id = id,报错
// 调用函数不携带参数获取外层全局变量的正确方法 let id = 1 function b5(val = id){ return {val,name:'东方求败'} } console.log(b5()); // id : 1 ,name :'东方不败'
如果箭头函数只有一句话且没有返回值,可以在内容前面加void,不需要写大括号,直接写内容即可
let fooEmpty = () => void '无返回值'; console.log('无:',fooEmpty()); // 无: undefined
箭头函数有返回值
let fooHave = () => '有返回值'; console.log('有:',fooHave()); // 有: 有返回值
let foo = () => {a : 1} console.log(foo()); // undefined
上面例子是一种特殊情况,虽然可以运行,但的到的结果是错误的,因为大括号在箭头函数中被认为是代码块,这里的箭头函数并不是return了一个{a:1}的对象,而是执行了一个表达式 a : 1,表达式执行完成后结束运行,没有返回值。
正常的写法如下:
let foo2 = () => { return {a : 1} } console.log(foo2()); // {a : 1}
在参数部分传入对象,解构赋值
let foo3val = {id:1, name:'孙悟空'} let foo3 = ({id,name}) => console.log(`id:${id},名称:${name}`); foo3(foo3val) // id:1,名称:孙悟空
有了解构赋值后,箭头函数可以使表达更简洁、更加直观,例如这里封装一个简单的工具函数,一行代码完成求奇偶的工具函数封装
const isEven = n => n % 2 === 0 console.log(isEven(2)); // true console.log(isEven(3)); // false
普通函数写法
let fil = [1,2,3].filter(function(x){ return x == 2 }) console.log(fil); // [2]
箭头函数写法,一行搞定
let fil2 = [1,2,3].filter(el=> el == 2 ) console.log(fil2); // [2]
1、箭头函数没有this对象
2、不可以当做构造函数,也就是说,不可以对箭头函数使用new命令,否则报错
3、不能使用arguments对象,该对象在函数体内不存在
4、不能使用yield命令,因为箭头函数不能用作Generator函数
箭头函数导致this总是指向函数定义生效时所在的对象
在箭头函数的使用注意点中,最需要注意的就是this指向问题,这里举一个例子说明箭头函数this指向的问题
function arrows(){ console.log('name:',this.name); // 中国工艺美术史 setTimeout(()=>{ console.log('name:', this.name); // 中国工艺美术史 },100) setTimeout(function(){ console.log('name:', this.name); // 艺术概论 },100) } var name = '艺术概论' arrows.call({name : '中国工艺美术史'}) // name: 中国工艺美术史
call函数:第一个参数表示:想让
this指向的对象(obj)第二个参数表示:传进去的实参
如果
call的第一个参数未传值,或者传值为null,那么arrows中this指向为window这里传入第一个传参数,
this指向obj对象
第一个定时器setTimeout使用了箭头函数,在普通函数中,setTimeout指向的是window,但这里setTimeout使用了箭头函数,导致定时器指向的是调用函数定义生效时所在的对象,正常情况下,函数内部的this会指向当前驱动它的对象,这里箭头函数的this按理来说应该指向window(因为定时器的this指向window),但它却指向的是arrows所传入的对象(中国工艺美术史),也就是说箭头函数没有this,它的this引用的是arrows函数的this,所以这里打印的是 中国工艺美术史,而不是最外层全局变量 艺术概论 。
第二个定时器setTimeout没有使用箭头函数,即使使用call()方法,在函数内部的定时器还是指向window,因为定时器setTimeout的this指向是window。
箭头函数没有自己的
this,导致内部的this就是外层代码块的this。正是因为没有this,所以也就不能用作构造函数。
箭头函数里没有自己的this,而是引用外层的this。下面是 Babel 转箭头函数产生的 ES5 代码,就能清楚地说明this的指向。
// ES6 function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } // ES5 function foo() { var _this = this; setTimeout(function () { console.log('id:', _this.id); }, 100); }
1:对象内定义箭头函数
let cat = { level : 9, jumps : ()=> { this.level } }
在这个例子中,cat.jumps()是一个箭头函数,这是错误的。如果cat.jumps()是一个普通函数, 该方法内部的this指向cat。如果调用cat.jumps()是一个箭头函数时,this指向全局对象。因为对象不构成单独的作用域,导致jumps箭头函数定义时的作用域是全局作用域。
2:需要动态this的时候,不应该使用箭头函数
let button = document.getElementById('news') button.addEventListener('click',()=>{ this.classList.toggle('on') })
上面代码运行时,点击按钮报错,因为button监听函数是一个箭头函数,导致内部的this是全局对象。如果改成普通函数,this就会动态指向被点击的按钮对象。
另外,如果函数体很复杂,有许多行,或者函数内部有大量的读写操作,不单纯是为了计算值,这时也不应该使用箭头函数,而是要使用普通函数,这样可以提高代码可读性。
案例源码:https://gitee.com/wang_fan_w/es6-science-institute
如果觉得这篇文章对你有帮助,欢迎点亮一下star哟
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者