【问题标题】:Access es2015 class function member访问es2015类函数成员
【发布时间】:2015-12-16 23:44:48
【问题描述】:

'use strict';

class Test {
    lorem () {

    }

    static ipsum () {

    }
}

console.log(Test.lorem); // undefined
console.log(Test.ipsum); [Function]

有没有办法访问 Test.lorem?我试过 Test.prototype.lorem 和 Test.lorem 但都返回 undefined。

我要测试的函数的构造函数做了一些类似构造函数的事情,所以在单元测试中我只想直接从类中运行函数。

有什么想法吗?

【问题讨论】:

  • Test.prototype.lorem 不应返回未定义:babeljs.io/repl/…
  • 注意:这个 REPL 仍在使用 Babel 5.x,但很快就会升级到 Babel 6!这不是规范行为。请参阅下面的答案。

标签: javascript class ecmascript-6 babeljs


【解决方案1】:

该方法在prototype中可用。

Test.prototype.lorem

但是,请记住,直接调用此方法意味着this 将不会引用对象的实例。

Test.lorem 未定义,因为它不是静态方法。非静态方法被添加到prototype 对象中。

使用 ES2015 预设从 Babel 6 编译的证明。

'use strict';

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Test = (function () {
    function Test() {
        _classCallCheck(this, Test);
    }

    _createClass(Test, [{
        key: 'lorem',
        value: function lorem() {}
    }], [{
        key: 'ipsum',
        value: function ipsum() {}
    }]);

    return Test;
})();

console.log(Test.prototype.lorem);

【讨论】:

  • 对了一半...它们已添加到原型中,但在那里不可用;看我的回答。
  • @lededje 查看我添加的代码 sn-p,并检查您的开发者控制台。使用带有 ES2015 预设的 Babel 6,我从原型访问方法没有任何问题。
【解决方案2】:

除非是静态成员,否则不应执行没有实例的方法。

这是大多数(如果不是全部)面向对象语言中的一个非常基本的概念。

如果您只想获取函数的引用,使用类原型确实可行。

顺便说一句,你实际上可以在没有实例的情况下执行方法,因为 JavaScript 确实允许这种灵活性,但你应该避免这种做法。

【讨论】:

  • 真的吗?我认为class 语法只是对允许这样做的现有原型系统的约束。有趣...
  • @JeremyBanks 正确,可以通过原型访问函数。
  • 是的——这个答案是错误的。也许 OP 对他自己的代码有误,或者 Babel 正在产生非标准行为。我刚刚使用 Chrome 的原生实现 Test.prototype.lorem() 通过它的原型执行了这个非静态方法,它按我的预期工作。
  • @JeremyBanks - 是的,您可以访问该函数,但您应该有一个计划调用它的实例。在这一点上,我的回答可能不够清楚。
【解决方案3】:

你需要一个Test的实例。

class Test {
      lorem () {
        console.log('test');
      }

      static ipsum () {

      }
  }

  var test = new Test();
  test.lorem();

或者你可以这样做

Test.prototype.lorem();

【讨论】:

  • 并非如此;看我的回答。
【解决方案4】:

不知道为什么我得到了 -1 但 w/e

类方法在 ES2015 中是不可枚举的

您不能直接访问非静态的类成员。

https://phabricator.babeljs.io/T959

【讨论】:

  • 即使它不可枚举,它应该仍然可以访问。
  • 显然没有,试图在官方规范中找到这个。
  • 据我所知,该链接讨论的是console.log(Foo.prototype); 是如何产生{ bar: [Function: bar] },而不是{},这是一个完全独立的问题。查看我答案中的 sn-p。
  • 再说一次,不是我所看到的。这个要点在标题中给了我一个前后的版本。 gist.github.com/lededje/7fda648db11b0e26dddd
  • 那是因为你的测试有缺陷。尝试将console.log(Test.prototype.lorem); 添加到test.js,它会起作用。它不是静态方法,所以它在原型中。
猜你喜欢
  • 2012-10-08
  • 1970-01-01
  • 2019-10-16
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 2022-01-10
相关资源
最近更新 更多