javascript 中的箭头函数 ( => ) 和普通函数 ( function ) 有什么区别?

本文深入探讨了JavaScript中箭头函数的this绑定特性及其与普通函数的区别。通过具体示例展示了箭头函数如何沿作用域链查找this,并解释了箭头函数不自动绑定局部变量的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我当时想的就是:这个问题很简单啊~(flag),然后做出了错误的回答……

箭头函数中的this 和调用时的上下文无关,而是取决于定义时的上下文一旦定义,this就不会改变。

这并不是很正确的答案……虽然也不是完全错误。

箭头函数中的 this

首先说我的回答中没有错误的部分:箭头函数中的 this 确实和调用时的上下文无关

function make () { 
   return ()=>{ console.log(this); } 
} 

const testFunc = make.call({ name:'foo' }); 

testFunc(); // {name:'foo'} 
testFunc.call({ name:'bar' }); // {name:'foo'}

这个例子,箭头函数在定义之后,this就不会发生改变了,无论怎么调用它,this 都不会改变;

但严格来说,这并不是“取决于定义时的上下文”, 因为箭头函数根本就没有绑定自己的 this,在箭头函数中调用 this 时,仅仅是简单的沿着作用域链向上寻找,找到最近的一个 this 拿来使用罢了;
从效果上看,这和我之前的理解并没有多大偏差,但它们的本质却是截然不同,箭头函数并不是普通函数新增了 this 不受调用时上下文影响的特性,而是减少了很多特性;

箭头函数其实是更简单的函数

实际上箭头函数中并不只是 this 和普通函数有所不同,箭头函数中this不会自动绑定的局部变量,包括:this,arguments,super(ES6),new.target(ES6)……

借用别人的一个例子:普通函数中会自动绑定的局部变量。

function foo() { 
   setTimeout( () => { console.log("args:", arguments); },100);
}

foo( 2, 4, 6, 8 ); // args: [2, 4, 6, 8]

区别:

在普通函数中会自动绑定上的各种局部变量;  箭头函数都是十分单纯的沿着作用域链向上寻找,找到最近的一个 this 拿来使用。

箭头函数就是这么个简单、纯粹的东西;

所以我个人认为箭头函数更适合函数式编程,除了它更短外,箭头函数也不易被那些没有显示声明的变量影响,导致产生意外的计算结果;

那么普通函数能否实现和箭头函数一样的效果呢?

如果是像当初的我一样简单的考虑固定住 this 这个易变的家伙……那倒是很简单,有些常用的方法,比如这样:

function make () { 
  var self = this; 
  return function () { console.log(self); } 
}

或者

function make () { 
  return function () { console.log(this); }.bind(this); 
}

然而第二种方法只能固定 this 这一个变量而已,如前文所述,箭头函数中的 arguments 等变量也是从作用域链中寻找的,为了实现类似的效果,我们只有重新定义一个局部变量这一种方式,而 babel 也是使用这种方式对箭头函数进行处理的。

function make () { 
   return ()=>{ console.log(this); console.log(arguments); } 
} //babel it... 

function make() { 
   var _this = this, _arguments = arguments; 
   return function () { console.log(_this); console.log(_arguments); }; 
}

那么……如果我想在箭头函数中使用 arguments 该怎么办?

……我觉得如果你有这个需求,可能还是用普通函数更合适一点……

但并不是说在箭头函数中无法以类似数组的形式取到所有参数,我们可以利用展开运算符来接收参数,比如这样:

const testFunc = (...args)=>{ console.log(args) //数组形式输出参数 }

或许真的有场景需要用到这种写法,但我还是认为,箭头函数更适合那些接受固定的参数,返回一个计算结果的简单情况

以上所述是小编给大家介绍的普通函数和箭头函数的区别和用法详解,希望对大家有所帮助!

转载:https://wenda.so.com/q/1492960997206043

<think>嗯,用户想了解箭头函数的语法以及它普通函数区别。首先,我需要确保自己对这两个方面有足够的理解。箭头函数是ES6引入的,语法上确实比普通函数简洁。我应该先整理箭头函数的基本语法,包括不同参数函数体情况下的写法变化。比如,没有参数、单个参数、多个参数,以及函数体是否需要大括号return。 接下来是箭头函数普通函数区别。根据之前的引用资料,有几个关键点:语法差异、this绑定、arguments对象的使用、能否作为构造函数,以及prototype属性的存在否。需要逐一解释这些区别,特别是this的指向问题,这是箭头函数最重要的特性之一。普通函数的this是动态绑定的,而箭头函数继承自外层作用域,这对事件处理或者回调函数非常有用。 然后,我需要考虑用户可能的实际应用场景,比如在React中的事件处理,或者需要保持this上下文的情况。举一些例子会帮助用户理解,比如在setTimeout中使用箭头函数普通函数时this的不同表现。 还要注意引用资料中的内容,正确标注引用标识。例如,引用[1]提到箭头函数使用箭头符号定义,而普通函数function关键字;引用[4]提到this指向的不同。需要确保这些引用在适当的地方被引用,同时保持回答的流畅性。 用户可能还会有更深层次的需求,比如为什么箭头函数不能作为构造函数,或者为什么没有arguments对象。虽然用户没有直接问这些,但解释清楚这些点可以更全面地回答区别。此外,可以提到箭头函数在简洁性上的优势,比如单行返回时可以省略return,以及参数括号的省略情况。 最后,生成的相关问题需要覆盖用户可能进一步想了解的内容,比如this的具体应用场景、如何选择箭头函数普通函数,以及箭头函数的限制。这可以帮助用户自主深入学习,解决更多实际问题。</think>### 箭头函数语法及普通函数区别 #### 一、箭头函数语法特点 1. **基础语法格式** 箭头函数使用 `=>` 符号定义,语法形式根据参数函数体的复杂度变化: - **无参数时**:`() => { ... }` 示例:`const greet = () => console.log("Hello");` - **单参数时**:可省略括号 示例:`const square = x => x * x;` - **多参数时**:必须用括号包裹 示例:`const sum = (a, b) => a + b;` - **函数体为单条语句**:可省略 `{}` `return` 示例:`const isEven = num => num % 2 === 0;`[^4] 2. **多行函数体** 若函数体包含多条语句,需使用 `{}` 并显式返回结果: ```javascript const calculate = (x, y) => { const sum = x + y; return sum * 2; }; ``` --- #### 二、箭头函数普通函数区别 1. **语法简洁性** - 箭头函数省略 `function` 关键字,简化参数列表返回值书写[^1][^3] - 对比示例: ```javascript // 普通函数 function add(a, b) { return a + b; } // 箭头函数 const add = (a, b) => a + b; ``` 2. **this 绑定机制**(核心区别) - **普通函数**:`this` 动态绑定,取决于调用方式 ```javascript function Counter() { this.count = 0; setInterval(function() { this.count++; // 错误!此处this指向window }, 1000); } ``` - **箭头函数**:继承外层词法作用域的 `this`(静态绑定) ```javascript function Counter() { this.count = 0; setInterval(() => { this.count++; // 正确!this指向Counter实例 }, 1000); } ``` 3. **arguments 对象** - 箭头函数没有自己的 `arguments` 对象,需使用剩余参数语法: ```javascript const showArgs = (...args) => console.log(args); ``` 4. **构造函数能力** - 箭头函数不能作为构造函数,使用 `new` 调用会报错 ```javascript const Foo = () => {}; new Foo(); // TypeError: Foo is not a constructor ``` 5. **prototype 属性** - 箭头函数没有 `prototype` 属性[^2] 验证代码:`console.log( (() => {}).prototype ); // undefined` --- #### 三、使用场景对比 | 特性 | 箭头函数 | 普通函数 | |---------------------|-------------------|-------------------| | 需要动态this | ❌ | ✅ | | 作为构造函数 | ❌ | ✅ | | 需要arguments对象 | ❌ | ✅ | | 需要简洁的回调函数 | ✅ | ❌ | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值