一文搞懂箭头函数和普通函数的区别
1.箭头函数和普通函数的区别?
箭头函数(Arrow Function)和普通函数(Regular Function)在 JavaScript 中有一些区别,其中包括它们的语法、行为和对 this
的处理方式。
箭头函数和普通函数的区别:
- 语法:
- 箭头函数:使用
=>
符号定义,可以是匿名函数或命名函数。 - 普通函数:使用
function
关键字定义,可以是匿名函数或命名函数。
- 箭头函数:使用
this
的处理:- 箭头函数:箭头函数没有自己的
this
,它继承自外围(包含它的)函数或上下文**(在定义时就确定了,并且永远无法改变!)**。箭头函数的this
始终指向在定义函数时的外部作用域的this
值,无法通过call
、apply
、bind
方法来改变它的this
指向。 - 普通函数:普通函数的
this
取决于函数是如何被调用的,可以通过call
、apply
、bind
方法来显式地改变函数的this
指向。
- 箭头函数:箭头函数没有自己的
- arguments 对象: ——> 注意
- 箭头函数:没有自己的
arguments
对象,它会继承外围函数的arguments
。——> 和 this 一样也是会继承的 - 普通函数:有自己的
arguments
对象,可以通过该对象获取传递给函数的参数。
- 箭头函数:没有自己的
- prototype 属性:
- 箭头函数本身没有
prototype
属性,即原型对象。 - 普通函数有
prototype
属性。
- 箭头函数本身没有
- 构造函数: ——> 注意
- 箭头函数:不能用作构造函数(但它有构造函数),不能使用
new
关键字实例化。 - 普通函数:可以用作构造函数,使用
new
关键字可以创建实例。
- 箭头函数:不能用作构造函数(但它有构造函数),不能使用
2.箭头函数为什么不能用作构造函数?用 call 和 apply 可以改变箭头函数的 this 指向吗?
以下是一些解释为什么箭头函数不能用作构造函数或被实例化的原因:
没有自己的
this
绑定: 箭头函数中的this
值是由外层最近一层非箭头函数决定的。这使得箭头函数无法像普通函数一样绑定一个新的对象实例。构造函数通常需要一个新的对象作为this
值(在调用构造函数.call()方法时需要传入一个空对象作为作用域,然后给作用域赋值),但箭头函数没有自己的this
(所以箭头函数不能调用 call 方法修改 this 绑定,也就无法指定作用域,所以构造函数没办法给这个空对象赋值),所以无法满足构造函数的需求。一句话:它没有自己的 this,它没办法改变作用域,没办法把空对象指定为作用域,所以就没办法给对象构造属性!
没有
prototype
属性: 普通函数拥有一个prototype
属性,可以用于实现原型继承。而箭头函数没有这个属性,无法被用于创建对象实例或实现原型链。一句话:他没有 prototype 属性,无法实现对象和构造函数之间的原型链继承
语法简洁性: 箭头函数的设计目标之一是简化函数的写法,使代码更加简洁。因此,为了保持这种简洁性,箭头函数舍弃了一些传统函数的功能,包括构造函数的能力。
箭头函数不能使用 call 和 apply 改变箭头函数的 this 指向:箭头函数的 this 指向不可变!
箭头函数的 this
是在函数定义时确定的,无法通过 call
和 apply
来改变它的指向。当你使用 call
或 apply
调用箭头函数时,传递的第一个参数会被忽略,因为箭头函数不会创建一个新的执行上下文来设置 this
。在这种情况下,箭头函数的 this
仍然是继承自外部作用域的值,无法被修改。