ES6 Javascript:使用箭头函数从类中调用静态方法

6
尽管这样操作能达到预期的效果。
class ClassWithStaticMethod {

  static staticMethod() {
    return ('staticMethod');
  };

  static staticMethod2() {
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());
//staticMethod2 staticMethod

这是,

i) 使用类名可以访问staticMethod()方法,

ii) 这个方法可以使用"this"调用同一类中的另一个静态方法,

但这并不起作用。

class ClassWithStaticMethod {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = () => {
    const yee = this.staticMethod;
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());
//staticMethod2 undefined

就我的理解,我仍然可以访问staticMethod()方法,但是我无法访问第一个方法中的其他方法。我会得到未定义的结果,如果我使用

    const yee = this.staticMethod();

我遇到了一个错误

错误信息:TypeError: _this.staticMethod 不是一个函数


箭头函数的一个问题是它们具有通用的this作用域。(这就是为什么如果你想要更好的调用堆栈,我们必须使用function()。)在第二种方法中,this指的是调用上下文:window - weirdpanda
@weirdpanda - 这不是箭头函数的问题。这就是它们的设计和目的!如果你想要this的常规方法调用行为,那么请使用常规方法调用,而不是箭头调用。 - jfriend00
@jfriend00,非常抱歉,我的措辞有点不当。 - weirdpanda
2个回答

7
箭头函数继承它们的this来自于外部作用域,而不是依赖于它们的调用上下文。由于staticMethod2试图访问this.staticMethod,只有当this指向ClassWithStaticMethod时,即staticMethod2是一个标准函数,而不是箭头函数时,才能正常工作。
你还需要调用this.staticMethod(). (const yee = this.staticMethod;会将staticMethod强制转换为字符串,而不是调用它)
解决这两个问题,它就按预期工作了:

class ClassWithStaticMethod {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = function() {
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());


该死,你比我先完成了。 - weirdpanda
谢谢你们两位。所以真正的答案(一旦你理解了我的问题)是,在使用箭头函数时没有方法可以“解除”This,对吗? - GWorking
@Gerard 没错,当你使用箭头函数时,this将始终取决于this所在块的词法位置,而不会依赖于你如何调用它。 - CertainPerformance
@Gerard - 是的,当你不想让this像箭头函数一样工作时,请不要使用箭头函数。这就是它们的设计目的-这是它们存在的主要目的。如果您想要this的常规行为,请使用常规函数调用。或者使用.bind().call()与常规函数一起覆盖特定函数调用的this工作方式。使用适当的工具来完成工作。这不是箭头函数的问题。这就是它们的设计方式,您显然正在尝试将它们用于错误的目的。 - jfriend00
@jfriend00 是的,明白了 :) - GWorking

2
这里是关于箭头函数在一般使用时的一个怪异之处:它们具有通用的this作用域。(这就是为什么如果你想要更好的调用堆栈,我们必须使用function())。在第二种方法中,this指的是调用上下文:window
正如下面的注释所提到的,不要为了方便而使用简写语法;我们有这么多选项是有原因的。
为了解决这个问题,你可以使用function()来定义第二个函数;或者在对象的情况下使用()
然而,这样做是可以工作的:
class ClassWithStaticMethod2 {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = function() {
    console.log(this)
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

Check it out here.


正如我之前所说,这不是箭头函数的“问题”。这就是它们的设计初衷和主要用途。有些人会有点疯狂,试图在任何地方都使用更短的语法,即使箭头函数的主要功能不是所需的行为。那只是一种错误的模式。当您希望this值是词法作用域时,应使用箭头函数,而不是从对象.方法中获取它时。必须为适当的工作使用适当的工具。我建议您重新组织您的答案,更符合这些思路。 - jfriend00
我曾经看到Eran Hammer写的一段代码,他使用function而不是() => {}。有人问他为什么这样做,他的原因正是你所说的。在另一个讲座中,我听说使用... = function()的原因是因为() => {}会形成匿名函数,导致堆栈跟踪时无法识别。我的回答措辞有误,我将进行更正! - weirdpanda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接