Js面试题之——箭头函数与普通函数的区别

在项目开发中,包括面试的时候经常会遇到或问到箭头函数和普通函数有什么区别当我们猛然去想,好像一直以来只记得箭头函数中没有this,当我们在箭头函数中使用this会获取该函数上层的this值。那么除此之外,就没有其他区别了吗,当然不是。这里我们就来总结总结。

mdn中对箭头函数特点的描述是这样的:箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且不能作构造函数。

由此可以看出箭头函数和普通函数的区别有以下几点:

  • 语法形式不同,箭头函数更简短
  • 没有单独的this
  • 通过callapply调用会忽略第一个参数,只能传递参数,不能绑定this
  • 不绑定arguments
  • 不能使用new操作
  • 没有prototype属性
  • 不能使用yield关键字
  • 箭头函数具有与常规函数不同的特殊运算符优先级解析规则

在箭头函数书写过程中也有一些需要注意的点:

  • 返回对象字面量需要在外层添加小括号
  • 箭头函数和箭头之间不能换行

箭头函数与普通函数的区别

语法形式不同,箭头函数更短

这里就不多做赘述,mdn上的例子已经非常全面了。

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // 返回数组:[8, 6, 7, 9]

// 上面的普通函数可以改写成如下的箭头函数
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map(element => {
 return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号
elements.map(element => element.length); // [8, 6, 7, 9]

// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

箭头函数没有单独的this

这算是箭头函数与普通函数区别中最为重要的一点了,毕竟this的使用还是很频繁的。
在箭头函数出现之前,每一个新函数根据他是如何被调用的来定义这个函数的this值:

  • 如果该函数是一个构造函数,this指针指向一个新生成的对象。
  • 在严格模式下的函数调用下,this指向undefined
  • 如果该函数是一个对象的方法,则它的this指向这个对象
    等,详细内容可以看this指向
    在箭头函数中不会创建自己的this,它只会从自己的作用域链的上一层继承this。我们可以看一下具体案例:
function Person(){
  console.log(this);	// Person {}

  setTimeout(() => {
    console.log(this);	//Person {}
  }, 1000);
}

var p = new Person();

我们可以看到第一个this是按照普通函数this指向来指定的,指向了新生成的p变量。但是在setTimeout的回调箭头函数中的this与其上层函数Person函数完全相同。

通过call或apply调用会忽略第一个参数,只能传递参数,不能绑定this

由于箭头函数没有自己的this指针,通过call()apply()方法调用一个函数时,只能传递参数(不能绑定this),第一个参数会被忽略,同样的使用bind()调用是一样的。当然也不会报错,函数会被正常调用,只是不会绑定this值。

let fun = (num1, num2) => {
    console.log(num1);
    console.log(num2);
    console.log(this);
}
let arr = new Array();
fun.call(arr, 2, 3);	// 2	3		Window

fun.call(2, 3);	// 3	undefined		Window

不绑定arguments

箭头函数不绑定arguments对象。

var args = function(){
    return arguments[0]
}
var arr = () => arguments[0];
args(1)	//	1
args(1)	// VM1109:1 Uncaught ReferenceError: arguments is not defined

我们可以通过剩余参数来得到传入的实际参数。

var arr = (...args) => args;
arr(1, 2)	//	[1, 2]

不能使用new操作

箭头函数不能用作构造器,和new一起用会抛出错误。

let Fun = () => {}
let fun = new Fun()	//	VM1867:1 Uncaught TypeError: Fun is not a constructor

没有prototype属性

箭头函数没有prototype属性,也就没有constructor了。

let Fun = () => {}
console.log(Fun.prototype)	//undefined

不能使用yield关键字

yield 关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作函数生成器。

箭头函数具有与常规函数不同的特殊运算符优先级解析规则

 let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};
// Uncaught SyntaxError: Malformed arrow function parameter list

callback = callback || (() => {});    // ok

箭头函数语法注意点

返回对象字面量需要在外层添加小括号

在箭头函数中,只有一个返回的话可以不用写return,(a, b) => {a + b}就表示会把传过来的参数相加。但是如果我们要返回一个字面量的对象,直接写成(a, b) => {sum: a + b}是不可以的,因为解析的时候会把{}内部作为一个代码块去解析。

let sum = (a, b) => {sum: a + b}
console.log(sum(1, 2))	// undefined

let sum = (a, b) => ({sum: a + b})
console.log(sum(1, 2))	// {sum: 3}

箭头函数在参数和箭头之间不能换行

let sum = (a, b) 
						=> {a + b}	//	Uncaught SyntaxError: Unexpected token '=>'
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值