这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
前言
es6标准还没出来之前,我们一直使用的是普通函数
就比如下面写法:
function fn () {
console.log('你好,我是答案cp3!')
}
fn() // 你好,我是答案cp3!
es6标准出来后,增加了箭头函数(Arrow Function),今天来讲讲它和普通函数的区别。
箭头函数
语法:
(args1,args2) => {return xxx}
对比普通函数,去掉了function, 替换成了=>
普通函数定义的方式有两种:一种是函数声明,另一种是函数表达式
// 函数声明
function fn () {}
// 函数表达式
let fn = function () {}
箭头函数只能使用函数表达式
let fn = () => {}
写法还有以下区别:
- 如果只有一个参数,可以省略括号
=>后面的语句如果可以直接return的话,可以省略{}和return
let fn = (a) => { return a }
// 可以写成
let fn = a => { return a }
// 还可以改写成
let fn = a => a
这三个函数运行效果时一样的。对比普通函数,箭头函数写法是相对简洁一点。
下面继续讲讲它在用法上跟普通函数的区别。
-
箭头函数没有创建自己的this,而是继承了它在定义时上层作用域的this,并且后面不会再次改变。
var obj = { fn: function() { console.log(this) } } obj.fn() // obj对象 var obj = { fn: () => { console.log(this) } } obj.fn() // window对象从以上例子可以看出,
调用普通函数时,它的this指向调用时所处的对象,此时是
obj而调用箭头函数时,它的this指向是定义时上层的作用域的this,因为我是在
chrome的控制台运行的,这时上层的作用域的this是指向window,所以打印出window对象。 -
由于箭头函数的this一旦定义后就无法改变,所以
apply,call,bind等方法无法改变箭头函数的指向。let fn = function() {console.log(this)} fn.call({a:123}) // ({a:123} let fn = () => {console.log(this)} fn.call({a:123}) // window对象 -
因为箭头函数内部没有自己的this,所以也就不能用作构造函数
let fn = function () {} new fn() // fn实例 let fn = () => {} new fn() // Uncaught TypeError: fn is not a constructor -
箭头函数内部没有
arguments对象let fn = function() {console.log(arguments)} fn() // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ] let fn = () => {console.log(arguments)} fn() // Uncaught ReferenceError: arguments is not defined -
箭头函数没有
prototype属性let fn = function() {} console.log(fn.prototype) // {constructor: ƒn} let fn = () => {} console.log(fn.prototype) // undefined -
箭头函数内部不可以使用
yield命令,因此箭头函数不能用作Generator函数。let fn = function *() { yield '答案cp3' } let fn1 = fn() fn1.next() // {value: "答案cp3", done: false} let fn = *() => { yield '答案cp3' } let fn1 = fn() fn1.next() // Unexpected token '*'
总结
以上就是我总结的箭头函数的使用,箭头函数和普通函数还是有很大区别。
不同的场景上选择使用不同的函数,大家可以自由选择。