JavaScript中的普通函数和箭头函数
最近被问到了一个问题:
javaScript 中的箭头函数 ( => ) 和普通函数 ( function ) 有什么区别?
我当时想的就是:这个问题很简单啊~(flag),然后做出了错误的回答……
箭头函数中的 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 这个易变的家伙……那倒是很简单,有些常用的方法,比如这样:
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) //数组形式输出参数
}
或许真的有场景需要用到这种写法,但我还是认为,箭头函数更适合那些接受固定的参数,返回一个计算结果的简单情况;
特别感谢 vajoy 所译 getify 大神的文章,把我从错误的理解上引导回来;
同时也让我明白了,有些时候代码运行的结果和你的预期相同,未必就代表代码运行的原理和你的理解相同
如果这篇文章中有什么错误或不足,欢迎指正
JavaScript中的普通函数和箭头函数的更多相关文章
- JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
<JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...
- JS中的普通函数和箭头函数
最近被问到了一个问题: >javaScript 中的箭头函数 (=>) 和普通函数 (function) 有什么区别? 我当时想的就是:这个问题很简单啊~(flag),然后做出了错误的回答 ...
- 博文推荐】Javascript中bind、call、apply函数用法
[博文推荐]Javascript中bind.call.apply函数用法 2015-03-02 09:22 菜鸟浮出水 51CTO博客 字号:T | T 最近一直在用 js 写游戏服务器,我也接触 j ...
- 6 JavaScript函数&内置构造&函数提升&函数对象&箭头函数&函数参数&参数的值传递与对象传递
JavaScript函数:使用关键字function定义,也可以使用内置的JavaScript函数构造器定义 匿名函数: 函数表达式可以存储在变量中,并且该变量也可以作为函数使用. 实际上是匿名函数. ...
- Javascript中call、apply、bind函数
javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...
- JavaScript中bind、call、apply函数用法详解
在给我们项目组的其他程序介绍 js 的时候,我准备了很多的内容,但看起来效果不大,果然光讲还是不行的,必须动手.前几天有人问我关于代码里 call() 函数的用法,我让他去看书,这里推荐用js 写服务 ...
- JavaScript中以构造函数的方式调用函数
转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明. ...
- 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化
项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...
- 普通函数跟箭头函数中this的指向问题
箭头函数和普通函数的区别如下. 普通函数:根据调用我的人(谁调用我,我的this就指向谁) 箭头函数:根据所在的环境(我再哪个环境中,this就指向谁) 一针见血式总结: 普通函数中的this: 1. ...
随机推荐
- 极简配置phpstorm+xdebug进行断点调试
以前调试的时候各种var_dump()就能得到结果,现在入手别人开发的工作,由于不了解业务和代码逻辑,又要去修改bug,就造成了修改bug效率低,所以又拾起来了xdbug,顺便总结了一下phpstor ...
- 微服务化的不同阶段 Kubernetes 的不同玩法
欢迎访问网易云社区,了解更多网易技术产品运营经验. 作为容器集群管理技术竞争的大赢家,Kubernetes已经和微服务紧密联系,采用Kubernetes的企业往往都开始了微服务架构的探索.然而不同企业 ...
- Goole Search Auto Complete
这个项目就九章算法大数据课程的一个项目.主要分为两步: 第一步是 offline 建立 数据库 我们用两个map reduce 的data pipline 来实现. 第二步是 online显示把数据里 ...
- quagga源码学习--BGP协议对等体连接建立的状态机
创建完bgp peer之后,就要bgp start了,不然费那么大劲创建出来不做事情就销毁了,就很尴尬了. 那么对等体一旦start起来,就会进入各自的状态,在不同的状态下处理各自的事件消息. 下面列 ...
- [cocos2dx enhancement] CCPlatformMacros.h
为了更好的调试Log,优化CCLOG格式 path: cocos2dx/platform/CCPlatformMacros.h line 218: #define CCLOGERROR(format, ...
- NSByteCountFormatter
可以将字节转化为我们需要的Kb或者m + (NSString *)stringFromByteCount:(long long)byteCount countStyle:(NSByteCountFor ...
- BZOJ 3625 [Codeforces Round #250]小朋友和二叉树 ——NTT 多项式求逆 多项式开根
生成函数又有奇妙的性质. $F(x)=C(x)*F(x)*F(x)+1$ 然后大力解方程,得到一个带根号的式子. 多项式开根有解只与常数项有关. 发现两个解只有一个是成立的. 然后多项式开根.求逆. ...
- 论S B的自我修养 【2015/10/18更】
to do list: 1.正则表达式引擎 (done 2.五子棋AI jquery && canvas 游戏 (这个搞定好多好玩的idea可以实现了php 暂时不想玩各种框架吧, ...
- 检测字符串当中x与o的数目是否相等
题目如上 答案 function XO(str) { var arr = str.split(""), xCount = , oCount = ; var reX = /x/i, ...
- Jib构建你的第一个java镜像
jib Official:GoogleContainerTools/jib 本文示例完整demo github地址 github.com/moxingwang/- 想要了解并且使用jib,首先你得知道 ...