V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
searene
V2EX  ›  Node.js

请问这段 js 代码为什么会输出 undefined?

  •  
  •   searene · 2017-04-23 21:50:24 +08:00 · 4119 次点击
    这是一个创建于 2771 天前的主题,其中的信息可能已经有所发展或是发生改变。

    平时 js 写的不多,以下代码有个地方不太明白。

    let func = () => ({
        a: 1,
        b: () => {
            return this.a;
        }
    });
    let instance = func();
    console.log(instance.b()); // undefined
    

    我记得如果this在一个函数里面的话,this会被设定为这个函数的调用者。在上面这段代码里调用b的是instance,所以this应该就是instance。显然instance.a === 1是成立的,那为什么this.a会返回undefined

    11 条回复    2017-10-09 10:30:02 +08:00
    FlowMEMO
        1
    FlowMEMO  
       2017-04-23 21:55:30 +08:00
    ZZZZZZZZTC
        2
    ZZZZZZZZTC  
       2017-04-23 21:57:43 +08:00
    ()=>{} 貌似使用 this 会出错
    bdbai
        3
    bdbai  
       2017-04-23 21:59:50 +08:00 via iPhone
    箭头函数没有 this ,用到的是外层的 this 。这里最外层的 this 就是 undefined 。
    你可以把箭头函数改成普通函数表达式再试试。
    aleen42
        4
    aleen42  
       2017-04-23 22:10:30 +08:00
    Arrow functions 会有一个 lexical this 的特性,因此函数中的 this 并非指向函数自身,而是外面一层,如 Window
    aleen42
        5
    aleen42  
       2017-04-23 22:12:53 +08:00   ❤️ 1
    所以你的代码在 ES5 等同:

    var self = this;
    function func() {
    return {
    a: 1,
    b: function () {
    return self.a;
    }
    };
    }
    SourceMan
        6
    SourceMan  
       2017-04-23 22:13:10 +08:00 via iPhone
    this 是外层的,不是 func 的,箭头函数导致的
    你可以看看 babel 转换后的
    loy6491
        7
    loy6491  
       2017-04-24 18:03:49 +08:00   ❤️ 1
    所以一般写成
    b () {
    return this.a
    }
    TTPlayer
        8
    TTPlayer  
       2017-04-25 14:09:21 +08:00
    var func = function func() {
    return {
    a: 1,
    b: function b() {
    return undefined.a;
    }
    };
    };
    var instance = func();
    console.log(instance.b()); // undefined

    以上的 babel 转换成 es5 后的代码,可以参考一下
    inickel
        9
    inickel  
       2017-04-27 15:56:54 +08:00
    这里的 this 指向的是调用时的全局变量
    e8c47a0d
        10
    e8c47a0d  
       2017-10-09 10:27:05 +08:00
    箭头函数里不能用 this
    e8c47a0d
        11
    e8c47a0d  
       2017-10-09 10:30:02 +08:00
    可以改成这样

    let func = () => ({
    a: 1,
    b() {
    return this.a
    }
    })
    console.log(func().b())
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2010 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:52 · PVG 08:52 · LAX 16:52 · JFK 19:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.