引言
今天我经历了一场电话面试和一场线上笔试,这两者不是同一家公司,但却都考到了同一道题,那就是普通函数和箭头函数的区别 ,并且它们都给了我同样的一道题让我回答,这里我先把题目放在这,你们可以先自己尝试写一写,看看是否正确,答案会在文章末尾公布
window.name = '我是外部' let obj = { 'name': '我是内部', fn: function() { console.log(this.name); } } obj.fn() let fn = obj.fn fn() // 问:本段代码会返回什么结果
window.name = '我是外部' let obj = { 'name': '我是内部', fn: () => { console.log(this.name); } } obj.fn() let fn = obj.fn fn() // 问:本段代码会返回什么结果
因为作者之前写过一篇关于这两者的区别,因此本文就不再做过多的阐述,这里放上文章链接,建议大家花5分钟好好看看:千万别再一直无脑使用ES6的箭头函数了,它虽然很有用但并不是万能的
知识点
这里直接总结一下普通函数和箭头函数的区别:
- 普通函数中的this指向是运行时绑定的 ; 箭头函数中的this指向是定义时绑定的
- 普通函数有属于自己的this ; 箭头函数没有属于自己的this , 因此箭头函数中的this会自动向上找一个最近的this进行绑定
- 普通函数内有
arguments
对象 ; 箭头函数内没有arguments
对象
分析
接下来我们分别来分析一下文章开头的两段代码
第一段代码
考察普通函数的使用
window.name = '我是外部' let obj = { 'name': '我是内部', fn: function() { console.log(this.name); } } obj.fn() let fn = obj.fn fn()
关键: 普通函数内的 this
是运行时绑定的,所以 this
指向与函数的所处环境有关
首先在外部直接调用了 obj.fn()
,此时的函数是处于对象 obj
内的,因此 this
指向的就是该函数所处的环境,即 obj
。所以返回的是 我是内部
然后又将 obj
内部的 fn
函数赋值给了全局的变量 fn
,随即对其进行了调用,此时的函数处于全局环境中,因此 this
指向的就是全局环境,在浏览器中为 window
。所以返回的是 我是外部
第二段代码
考察箭头函数的使用
window.name = '我是外部' let obj = { 'name': '我是内部', fn: () => { console.log(this.name); } } obj.fn() let fn = obj.fn fn()
关键: 箭头函数中的 this
是定义时绑定的,并且其没有自己的 this
,所以它会向上寻找一个最近的 this
进行绑定
因为箭头函数中的 this
在定义时就绑定了,因此本段代码的两种调用方式效果是一样的
先来看 obj
中的 fn
箭头函数 ,其调用了 this
,但因其没有属于自己的 this
,所以就向上寻找,我们都知道,在JS中,普通函数和对象都有属于自己的 this
,因此 fn
中的 this
就和离它最近的 obj
中的 this
绑定了
显而易见,obj
的 this
指向的是全局,在浏览器中是 window
,因此答案就呼之欲出了,本段代码两次调用函数打印的结果都是 我是外部
总结
第一段代码的打印结果:
我是内部 我是外部
第二段代码的打印结果:
我是外部 我是外部
你答对了吗?