V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
enginex
V2EX  ›  JavaScript

关于箭头函数中 this 的一点理解

  •  
  •   enginex · 2017-10-20 16:04:16 +08:00 · 2763 次点击
    这是一个创建于 2590 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端新手,最近在补 JS 基础,参考了阮老师的《 ES6 入门》MDN 上关于 this 的解释,还有这篇文章

    目前关于箭头函数中 this 的理解,自己总结了如下三点:

    1. 箭头函数没有自己的 this,它指向函数定义时,外层普通函数的 this

    2. 外层普通函数的 this,可能会在函数调用时发生改变,进而导致箭头函数 this 的变化

    3. 因为箭头函数没有自己的 this,所以对其本身使用 call()、apply()、bind()方法都会失效

    想请教各位,小弟上面的理解,是否还存在偏差?

    另外,这篇文章中,如下代码:

    var name = 'window'
    
    function Person (name) {
      this.name = name
    
      this.show1 = function () {
        console.log(this.name)
      }
    
      this.show2 = () => console.log(this.name)
    
      this.show3 = function () {
        return function () {
          console.log(this.name)
        }
      }
    
      this.show4 = function () {
        return () => console.log(this.name)
      }
    }
    
    var personA = new Person('personA')
    var personB = new Person('personB')
    
    personA.show1() // personA
    personA.show1.call(personB) // personB
    
    personA.show2() // personA
    personA.show2.call(personB)// personA
    
    personA.show3()() // window
    personA.show3().call(personB) // personB
    personA.show3.call(personB)() // window
    
    personA.show4()() // personA
    personA.show4().call(personB) // personA
    personA.show4.call(personB)() // personB
    

    作者关于

    personA.show2.call(personB)// personA

    的解释是

    "因为构造函数闭包的关系,指向了构造函数作用域内的 this"

    我是否可以用上面总结的第 3 点(因为箭头函数没有自己的 this,所以对其本身使用 call()、apply()、bind()方法都会失效)来解释?是否有问题?

    感谢

    第 1 条附言  ·  2017-10-21 09:53:48 +08:00
    感谢 @KuroNekoFan 提醒,修改第 3 点如下:

    因为箭头函数没有自己的 this,所以对其本身使用 call()、apply()、bind()方法来修改 this 都会被忽略(而传参正常)
    8 条回复    2017-10-21 09:44:52 +08:00
    KuroNekoFan
        1
    KuroNekoFan  
       2017-10-20 16:54:19 +08:00
    我觉得解释应该是`call(personB)调用无效`
    enginex
        2
    enginex  
    OP
       2017-10-20 17:10:11 +08:00
    @KuroNekoFan 额,和用总结的第 3 点来解释,有什么差别吗?
    binux
        3
    binux  
       2017-10-20 17:24:20 +08:00
    根本不需要第三点,你看看 babel 是怎么编译 arrow function 的就知道了。

    function A() {
    var _this = this;

    this.a = function () {
    _this.name;
    };
    }

    _this 都写死了,你重新绑定有什么用?
    enginex
        4
    enginex  
    OP
       2017-10-20 17:34:57 +08:00
    @binux 嗯,我也是这么理解的,但怕哪天自己又忘了去瞎纠结,所以给自己又加了条
    KuroNekoFan
        5
    KuroNekoFan  
       2017-10-20 17:43:04 +08:00
    @enginex https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions mdn 是这么解释的
    Since arrow functions do not have their own this, the methods call() or apply() can only pass in parameters. thisArg is ignored.
    469054193
        6
    469054193  
       2017-10-20 17:48:24 +08:00
    箭头函数的 this 看作用域. 上层有 function 的话则 this 指向就是那个 function 的指向. 如果没有就是 window
    xieguanglei
        7
    xieguanglei  
       2017-10-20 17:57:48 +08:00
    不错,理解得挺对的
    enginex
        8
    enginex  
    OP
       2017-10-21 09:44:52 +08:00
    @KuroNekoFan 感谢提醒,差点忘了还有传参
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5164 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 09:28 · PVG 17:28 · LAX 01:28 · JFK 04:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.