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

[新手] 不懂就问.

  •  
  •   zyb201314 · 2021-04-19 23:01:38 +08:00 via Android · 2381 次点击
    这是一个创建于 1349 天前的主题,其中的信息可能已经有所发展或是发生改变。
    user={}
    user.name="张 S."
    function sayHi() {
    alert("hi " + this.name );
    }

    //function func(){alert(this.name)}
    let func = () => alert("hello " + this.name)
    user.f=sayHi
    user.f() //hi 张 S.
    user.ff= func
    user.ff() //为什么这里获取不了 this.name?
    13 条回复    2021-04-20 17:13:22 +08:00
    wiluxy
        1
    wiluxy  
       2021-04-19 23:07:24 +08:00   ❤️ 1
    箭头函数的 this 指向父级作用域
    HariopaNic
        2
    HariopaNic  
       2021-04-19 23:10:20 +08:00 via iPhone   ❤️ 1
    箭头函数的 this 指向指向箭头函数定义时所处的对象,而不是箭头函数使用时所在的对象
    IsaacYoung
        3
    IsaacYoung  
       2021-04-19 23:13:35 +08:00 via iPhone   ❤️ 1
    谷歌搜索 mdn this
    Jirajine
        4
    Jirajine  
       2021-04-19 23:17:56 +08:00 via Android   ❤️ 1
    这算是 js 的糟粕之一。
    其实这个完全可以不去了解。永远只在 class 方法中使用 this,永远使用箭头函数定义函数。
    zyb201314
        5
    zyb201314  
    OP
       2021-04-20 01:31:55 +08:00 via Android
    谢谢各位. 是否可理解为箭头函数的不支持 this ?
    learningman
        6
    learningman  
       2021-04-20 03:02:20 +08:00 via Android   ❤️ 1
    @zyb201314 支持啊,取父级的
    des
        7
    des  
       2021-04-20 08:05:17 +08:00 via iPhone   ❤️ 1
    糟粕+1
    是楼上有些人说的不太全面,箭头函数里的 this 是静态的,且不可变更的
    在明白 this 的机制前,不建议在箭头函数里面用 this,不然很容易用错
    gitdoit
        8
    gitdoit  
       2021-04-20 09:04:06 +08:00   ❤️ 1
    yunyuyuan
        10
    yunyuyuan  
       2021-04-20 10:26:59 +08:00   ❤️ 1
    js 的 this 确实糟粕,我新手期也被误导过
    zyb201314
        11
    zyb201314  
    OP
       2021-04-20 11:47:37 +08:00 via Android
    谢谢各位,让我明白了这是个坑.
    糟粕+1
    let user = {};
    user.name = "MR.Zhang";

    user.func=function(x){
    let y = x => x +"! " + this.name;
    return y(x);
    }

    // 等效于:
    /*
    user.func=function(x){
    return x +"! " + this.name
    }
    */

    console.log(user.func("你好"));
    libook
        12
    libook  
       2021-04-20 17:01:08 +08:00
    在很多编程语言中,“函数”更多指的是一种纯粹的代码语法结构,用于复用代码。

    在 JS 中 function 有三种功能:
    1. 函数式语法
    2. 对象构造函数
    3. 对象方法

    箭头函数仅具备上述第一条功能,更符合我们广义上对于函数的定义。

    当然也可能还有其他奇淫技巧,这里不讨论。

    在你的例子里,是希望给一个对象添加新方法,一个方法要想访问对象主体就要用 this 指令,而箭头函数不支持 this,所以箭头函数不能被用作声明方法。这时候你只能用 function 。

    你要清楚的是,你的 funciton 是在对象外部声明的,而 this 并不会因为你 user.ff= func 而“跑”到了 user 对象内部,而是依托 function 对 this 的支持,在你调用的时候,顺着 user.ff()这个调用路径向左找到了 user 对象。换言之,你完全可以同时把 func 赋值给多个对象的属性,你调用 user1.ff()的时候它就会去找 user1,当你调用 user2.ff()的时候它就会去找 user2,都能正确输出各自对象的 name 值。

    然后由于 JS 是非常灵活的一门语言,所以它并不限制你必须在对象的直接作用域内使用 this,所以你可以在箭头函数里使用 this,只不过这个 this 跟这个箭头函数没关系,就像在一个 for 块或者 if 块内使用 this 一样,它会一层一层向外层作用域找对象:
    1. 找到 function 的作用域内的时候,就按照前面说的 function 内 this 找对象的机制找此时这个 function 的调用路径左侧的对象;
    2. 找到对象的作用域内的时候,就直接用这个对象;
    3. 最终找到对象或者最终到全局对象(globalThis/window/global),然后就用全局对象。

    建议深入了解一下原型机制,特别是对象创建的原理,然后对比一下函数和箭头函数的区别。
    libook
        13
    libook  
       2021-04-20 17:13:22 +08:00   ❤️ 1
    恩,刚才想了想,对象是数据结构不是过程,其本身没有作用域,所以可以忽略第 2 条:
    > 2. 找到对象的作用域内的时候,就直接用这个对象;

    “在箭头函数内用 this 就和在 for 块或 if 块内用 this 是一样的”这一句应该就能解答你的疑问了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2561 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:04 · PVG 08:04 · LAX 16:04 · JFK 19:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.