千家信息网

es6中箭头函数和普通函数的区别有哪些

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章主要介绍es6中箭头函数和普通函数的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!区别:1、箭头函数的定义要比普通函数定义简洁、清晰得多,很快捷;2、箭头函数
千家信息网最后更新 2025年01月18日es6中箭头函数和普通函数的区别有哪些

这篇文章主要介绍es6中箭头函数和普通函数的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

区别:1、箭头函数的定义要比普通函数定义简洁、清晰得多,很快捷;2、箭头函数不会创建自己的this,而普通函数会;3、箭头函数不能作为构造函数使用,而箭头函数能作为构造函数使用;4、箭头函数没有自己的arguments,而箭头函数有。

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

箭头函数是前端面试环节的一个高频考点,箭头函数是ES6的API,相信很多人都知道,因为它的语法比一般的函数更简洁,所以深受大家的喜爱。

一、基本语法

ES6中允许使用箭头=>来定义箭头函数,具体语法,我们来看一个简单的例子:

// 箭头函数let fun = (name) => {    // 函数体    return `Hello ${name} !`;};// 等同于let fun = function (name) {    // 函数体    return `Hello ${name} !`;};

可以看出,定义箭头函在数语法上要比普通函数简洁得多。箭头函数省去了function关键字,采用箭头=>来定义函数。函数的参数放在=>前面的括号中,函数体跟在=>后的花括号中。

关于箭头函数的参数:

如果箭头函数没有参数,直接写一个空括号即可。

如果箭头函数的参数只有一个,也可以省去包裹参数的括号。

如果箭头函数有多个参数,将参数依次用逗号(,)分隔,包裹在括号中即可。

// 没有参数let fun1 = () => {    console.log(111);};// 只有一个参数,可以省去参数括号let fun2 = name => {    console.log(`Hello ${name} !`)};// 有多个参数let fun3 = (val1, val2, val3) => {    return [val1, val2, val3];};

关于箭头函数的函数体:

如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的JS表达式,可以省去函数体的大括号{ }。

let f = val => val;// 等同于let f = function (val) { return val };let sum = (num1, num2) => num1 + num2;// 等同于let sum = function(num1, num2) {  return num1 + num2;};

如果箭头函数的函数体只有一句代码,就是返回一个对象,可以像下面这样写:

// 用小括号包裹要返回的对象,不报错let getTempItem = id => ({ id: id, name: "Temp" });// 但绝不能这样写,会报错。// 因为对象的大括号会被解释为函数体的大括号let getTempItem = id => { id: id, name: "Temp" };

如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void关键字

let fn = () => void doesNotReturn();

箭头函数最常见的用处就是简化回调函数。

// 例子一// 正常函数写法[1,2,3].map(function (x) {  return x * x;});// 箭头函数写法[1,2,3].map(x => x * x);// 例子二// 正常函数写法var result = [2, 5, 1, 4, 3].sort(function (a, b) {  return a - b;});// 箭头函数写法var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);

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

1、语法更加简洁、清晰

从上面的基本语法示例中可以看出,箭头函数的定义要比普通函数定义简洁、清晰得多,很快捷。

2、箭头函数不会创建自己的this(重要!!深入理解!!)

我们先来看看MDN上对箭头函数this的解释。

箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this

箭头函数没有自己的this,它会捕获自己在定义时(注意,是定义时,不是调用时)所处的外层执行环境的this,并继承这个this值。所以,箭头函数中this的指向在它被定义的时候就已经确定了,之后永远不会改变。

来看个例子:

var id = 'Global';function fun1() {    // setTimeout中使用普通函数    setTimeout(function(){        console.log(this.id);    }, 2000);}function fun2() {    // setTimeout中使用箭头函数    setTimeout(() => {        console.log(this.id);    }, 2000)}fun1.call({id: 'Obj'});     // 'Global'fun2.call({id: 'Obj'});     // 'Obj'

上面这个例子,函数fun1中的setTimeout中使用普通函数,2秒后函数执行时,这时函数其实是在全局作用域执行的,所以this指向Window对象,this.id就指向全局变量id,所以输出'Global'。 但是函数fun2中的setTimeout中使用的是箭头函数,这个箭头函数的this在定义时就确定了,它继承了它外层fun2的执行环境中的this,而fun2调用时thiscall方法改变到了对象{id: 'Obj'}中,所以输出'Obj'

再来看另一个例子:

var id = 'GLOBAL';var obj = {  id: 'OBJ',  a: function(){    console.log(this.id);  },  b: () => {    console.log(this.id);  }};obj.a();    // 'OBJ'obj.b();    // 'GLOBAL'

上面这个例子,对象obj的方法a使用普通函数定义的,普通函数作为对象的方法调用时,this指向它所属的对象。所以,this.id就是obj.id,所以输出'OBJ'。 但是方法b是使用箭头函数定义的,箭头函数中的this实际是继承的它定义时所处的全局执行环境中的this,所以指向Window对象,所以输出'GLOBAL'。(这里要注意,定义对象的大括号{}是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中!!

3、箭头函数继承而来的this指向永远不变(重要!!深入理解!!)

上面的例子,就完全可以说明箭头函数继承而来的this指向永远不变。对象obj的方法b是使用箭头函数定义的,这个函数中的this永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。

4、.call()/.apply()/.bind()无法改变箭头函数中this的指向

.call()/.apply()/.bind()方法可以用来动态修改函数执行时this的指向,但由于箭头函数的this定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this的指向,虽然这么做代码不会报错。

var id = 'Global';// 箭头函数定义在全局作用域let fun1 = () => {    console.log(this.id)};fun1();     // 'Global'// this的指向不会改变,永远指向Window对象fun1.call({id: 'Obj'});     // 'Global'fun1.apply({id: 'Obj'});    // 'Global'fun1.bind({id: 'Obj'})();   // 'Global'

5、箭头函数不能作为构造函数使用

我们先了解一下构造函数的new都做了些什么?简单来说,分为四步: ① JS内部首先会先生成一个对象; ② 再把函数中的this指向该对象; ③ 然后执行构造函数中的语句; ④ 最终返回该对象实例。

但是!!因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错!

let Fun = (name, age) => {    this.name = name;    this.age = age;};// 报错let p = new Fun('cao', 24);

6、箭头函数没有自己的arguments

箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。

// 例子一let fun = (val) => {    console.log(val);   // 111    // 下面一行会报错    // Uncaught ReferenceError: arguments is not defined    // 因为外层全局环境没有arguments对象    console.log(arguments); };fun(111);// 例子二function outer(val1, val2) {    let argOut = arguments;    console.log(argOut);    // ①    let fun = () => {        let argIn = arguments;        console.log(argIn);     // ②        console.log(argOut === argIn);  // ③    };    fun();}outer(111, 222);

上面例子二,①②③处的输出结果如下:

很明显,普通函数outer内部的箭头函数fun中的arguments对象,其实是沿作用域链向上访问的外层outer函数的arguments对象。

可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表!!

7、箭头函数没有原型prototype

let sayHi = () => {    console.log('Hello World !')};console.log(sayHi.prototype); // undefined

8、箭头函数不能用作Generator函数,不能使用yeild关键字

以上是"es6中箭头函数和普通函数的区别有哪些"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

函数 箭头 对象 指向 参数 普通 例子 括号 环境 方法 全局 外层 简洁 只有 语法 输出 作用 写法 就是 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 java单元测试内存数据库 淄博张店网络安全张召峰简历 怒江统计年鉴数据库 我们共同守护网络安全抖音 本地服务器搭建v2 关于维护网络安全的宣传 上海im聊天软件开发公司 打印服务器 添加打印机 数据库日期取月日 法院有网络技术科吗 sql数据库显示二进制名 三级网络技术2021年新增题库 安卓系统硬件检测软件开发 邯郸市尔文网络技术服务有限公司 郑州公交打造网络安全主题线路 Perion网络技术公司 tcga数据库33种癌症 静安区软件开发信息推荐 软件开发应该考计算机的什么 阿里网络安全员工资一般多少 自编选号池未上牌数据库 开票服务器管理系统网址 数据库慢sql文件目录 网络安全创建全国文明城市 客户端与服务器连接闪断 数据库安全服务翻译 租用服务器怎么选择合适的系统 mc服务器被迷你炸了损失多大 深圳市中移互联网科技 网吧网络安全技术措施
0