箭头函数的意义和函数的二义性

前言

说到 箭头函数,可能很多人的第一反应就是和普通函数的区别:

  1. 箭头函数没有this,普通函数的this指向依赖它是如何被调用的
  2. 箭头函数没有arguments对象,而是通过剩余参数(rest parameters)来获取所有参数的值
  3. 箭头函数没有prototype原型,不能用作构造函数,而普通函数可以
  4. 更加简洁的函数语法

相信一名前端开发者,对于这两者的区别,多多少少都能罗列一些,但是你们有没有想过,JS已经有普通函数了,为什么还要有箭头函数?难道仅仅只是语法简洁可读性好这么简单?

答案只有一个:消除函数的二义性。

函数的二义性

那什么是函数的二义性呢?

我们创建一个普通函数:

javascript 复制代码
function user(){}

这个时候就会出现歧义,因为这个函数有两种调用方式:

javascript 复制代码
function user(){};

//  普通方式调用
user();

// 当做构造函数调用
new user();

这就是函数的二义性,至于为什么会出现这种情况,这个就要追溯到JS的历史渊源了,我感觉应该是JS这门语言在设计上的缺陷。

因为函数的二义性,导致JS函数的复杂度直线上升,因为函数在创建的时候,创建者不知道未来的调用者如何调用,可能直接调用,也有可能通过new方法调用,这就会存在很大的安全隐患。

后来开发者就在函数的命名上定义了一套规范,普通函数首字母小写,构造函数首字母大写,就像下面这样:

javascript 复制代码
//  普通函数
function user(){};

// 构造函数
function User(){};

但毕竟这个不是强约制性的,普通函数依旧可以使用new调用,这只能说在一定程度上稍微缓解了这个问题,就像JS一些构造函数一样,两种调用方式都可以,比如:

javascript 复制代码
//  Number
Number();
new Number()

// Date
Date();
new Date();

如果你想普通函数不能通过new来调用,你可以这么做:

javascript 复制代码
function User(){
  if(new.target){
    throw('Uncaught TypeError: User is not a constructor')
  }
}

所以调用者压根就不清楚函数的调用方式,这个函数的二义性,会给开发者造成心智负担。 官方一直都知道这个问题,只是一直没解决,后来ECMAScript 6在给JS打补丁的时候,引入了两个概念:

  1. 箭头函数
  2. class实例

它们的作用都是为了消除函数的二义性。

箭头函数只能这样调用:

javascript 复制代码
const user = () => {};

// 报错 Uncaught TypeError: user is not a constructor
const a = new user();

// 正确
user();

class只能这样调用:

javascript 复制代码
class User{};

// 报错 Uncaught TypeError: Class constructor User cannot be invoked without 'new'
const user = User();

// 正确
const user = new User();

箭头函数

那为什么箭头函数里边没有this和原型?

javascript 复制代码
const user = () => {};
console.log(user.prototype); // undefined

因为箭头函数跟实例无关,跟面向对象没关系,它已经脱离了面向对象的范畴,而this哪来的?this来自于面向对象里面的概念,箭头函数里面没有原型的概念是一样的。

相关推荐
jktantan2 小时前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
总要学点什么2 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
2601_962885723 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
excel3 小时前
encodeURI 和 encodeURIComponent 有什么区别?
前端
前端精髓3 小时前
调用openrouter的免费API模型
java·前端·javascript
赛博守夜人4 小时前
AI安全攻防与治理之十四:AI 安全测试不能脱离传统安全,Web、API、移动端与模型攻击面的组合拳
前端·人工智能·安全
开开心心_Every4 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
networknomad4 小时前
OpenReplay:自己搭的会话回放工具,给前端排错用的
前端·其他
缓慢更新5 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
陈随易5 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员