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

使用 call()方法调用函数 和 将作用域 this 直接作参数传入有什么区别?

  •  
  •   gromit1337 · 2020-05-30 17:25:09 +08:00 · 2899 次点击
    这是一个创建于 1674 天前的主题,其中的信息可能已经有所发展或是发生改变。
    小程序里的一个封装方法需要调用页面的组件, 要用到 this.selectComponent().doThing() ,这里引起了标题的争议了
    第 1 条附言  ·  2020-06-03 09:48:10 +08:00
    突然觉得这贴应该发到小程序节点 , 场景是这样的 , 我们登录是做成组件浮出 , 封装好的请求方法里携带 AccessToken , 没有就调起登录 , 所以在方法里需要调用登录组件 selectComponent().show() , 然后就出现主题所说的了 .
    21 条回复    2020-06-05 13:01:43 +08:00
    gromit1337
        1
    gromit1337  
    OP
       2020-05-30 17:35:40 +08:00
    感觉用 call 少了个参数,少了些思想负担😂,但是我的后端同事们好像对 es2015 之后的语法都很排斥
    liuy1994g
        2
    liuy1994g  
       2020-05-30 18:43:02 +08:00
    this 和参数还是有些区别的吧
    rabbbit
        3
    rabbbit  
       2020-05-30 19:05:28 +08:00
    面向对象编程和函数式编程?
    ChanKc
        4
    ChanKc  
       2020-05-30 21:41:08 +08:00
    没有太看懂
    this.selectComponent()和 selectComponent.call(this)的差别?
    在你的情况下似乎没区别
    call 一般都发生在,如果你要调的这个方法,你担心没有
    比如你的 this.selectComponent == null
    此时你只能去找别的类似的对象的方法拿过来用一下
    that.selectComponent.call(this)

    示例:
    let obj = Object.create(null);
    obj.a = 1;
    Object.prototype.hasOwnProperty.call(obj,"a"); // true
    ChanKc
        5
    ChanKc  
       2020-05-30 21:51:13 +08:00
    想了想你可能要的是这个
    你的 selectComponent 只是临时用一下,比如
    let obj = {};
    obj.selectComponent = function () { console.log("s") };
    obj.selectComponent();
    delete obj.selectComponent;

    如果是这样,用 call
    (function selectComponent () {}).call(obj);

    前者可能会覆盖已有的同名方法,而且可能忘记 delete 从而影响 Object.keys 等方法的结果。call 没有那么地“侵入性”
    ChanKc
        6
    ChanKc  
       2020-05-30 22:03:54 +08:00
    还是说你问的是
    func sum(self) {return self.a + self.b };
    func sum() { return this.a + this.b };
    的区别?我个人喜欢前者
    longjiahui
        7
    longjiahui  
       2020-05-31 00:15:56 +08:00
    如果不是某个类对象或啥有意义的 this,感觉通过参数传会比较好。
    不然 要搞清楚这个 this 会慢慢变得复杂
    gromit1337
        8
    gromit1337  
    OP
       2020-05-31 12:23:57 +08:00
    @ChanKc #6 大概是你这两个的区别,下面的方法用 call 调用
    Austaras
        9
    Austaras  
       2020-05-31 13:35:55 +08:00   ❤️ 1
    这两个都不好, 用 arrow function
    pvgjfk
        10
    pvgjfk  
       2020-05-31 19:58:16 +08:00
    在功能性上没啥区别,都能实现你的目的.
    pvgjfk
        11
    pvgjfk  
       2020-05-31 20:30:08 +08:00
    忘了说了,如果你是我同事你这样写会被我骂的 [狗头]
    autoxbc
        12
    autoxbc  
       2020-06-01 06:22:17 +08:00
    this 本质上就是隐式传参数,隐式的目的是写起来简洁优雅,不简洁不优雅反而烧脑的用法都是错的,背离了设计初衷
    ChanKc
        13
    ChanKc  
       2020-06-01 08:34:35 +08:00 via Android
    @gromit1337 没啥区别,但是如果是 typescript,涉及到 private 的话,#6 上面那个是不行的
    ChanKc
        14
    ChanKc  
       2020-06-01 08:38:06 +08:00 via Android
    @autoxbc this 不是 js 里最烧脑的东西之一吗
    gromit1337
        15
    gromit1337  
    OP
       2020-06-01 09:32:05 +08:00
    @pvgjfk #11 为什么 /doge
    autoxbc
        16
    autoxbc  
       2020-06-01 20:58:29 +08:00
    @ChanKc #14
    this 没有解决任何重要的问题,只是隐式传参的语法糖。当语法糖吃起来苦时,就是本末倒置了。那些试图用 this 炫技的人,其实不理解这个东西
    ChanKc
        17
    ChanKc  
       2020-06-01 22:20:37 +08:00 via Android
    @autoxbc 没太懂,什么是拿 this 炫技?如果不懂 this 又怎么拿 this 炫技?
    pvgjfk
        18
    pvgjfk  
       2020-06-03 00:20:40 +08:00
    @gromit1337 了解下函数式编程思想就知道了, 既然你能把一个函数设计成纯函数, 那么为什么要多加一个 this 入参使其变为非纯函数呢.
    pvgjfk
        19
    pvgjfk  
       2020-06-03 00:23:43 +08:00
    况且你将 _this 作为参数传入, 这个参数的逻辑和函数内的 this 就已经冗余了, 这么设计函数很明显不合理.
    gromit1337
        20
    gromit1337  
    OP
       2020-06-03 09:28:05 +08:00
    @pvgjfk #19 但是我拿不到调用函数时候的上下文啊 , this.selectComponent()就没法起作用
    ChanKc
        21
    ChanKc  
       2020-06-05 13:01:43 +08:00
    @gromit1337 如果类似于#6 的案例
    我看 Cay S. Horstman 提出的 golden rule 说
    Don’t use this outside constructors or methods.
    也就是不要在类以外的地方使用 this
    Douglas Crockford 的做法更极端,他完全不用 this 。
    我觉得普通的函数,不是属于特定类或者具有特定“shape”的对象的方法的函数就最好不要出现 this
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2070 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 16:12 · PVG 00:12 · LAX 08:12 · JFK 11:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.