【问题标题】:How can I differentiate between an arrow function, class and a normal function?如何区分箭头函数、类和普通函数?
【发布时间】:2015-11-03 09:16:40
【问题描述】:

如何在 ES6 中使用它的引用来区分这三样东西?

let x = i => i+1;

class y { constructor(i) { this._i=i+1; } get i(){ return this._i;} }

function z(i) { return i+1; }

例子:

test(x) //=> 'arrow'
test(y) //=> 'class'
test(z) //=> 'function'

我如何在转译器中区分这些东西 - Traceur / Babel?

【问题讨论】:

  • 你的用例是什么?我会尝试调用 func.toString() 看看我得到了什么并可能分析它。
  • 我强烈建议类名遵循构造函数首字母大写的长期传统。这样就很容易一眼看出Function() 是类还是构造函数,而function() 是函数。

标签: javascript ecmascript-6 arrow-functions


【解决方案1】:

如何在 ES6 中区分这些东西?

  • 箭头函数是不能用作构造函数的函数,并且没有.prototype 属性。但是,方法也不行。它们继承自 Function.prototype
  • 类是不能在没有new 的情况下调用的函数,并且具有通常不为空的.prototype 对象。如果使用了 extends 关键字,它们不会继承自 Function.prototype
  • 函数是可以任意调用的函数,并且确实有一个.prototype,即normally empty。它们继承自 Function.prototype
  • 生成器函数是具有.prototype 的函数,该.prototype 继承自内部GeneratorPrototype 对象,并且它们继承自内部Generator 对象。

如您所见,有一些线索。但是,属性和继承总是会被弄乱,所以你不能真正相信它。函数是否是构造函数(可以用new 调用)无法从外部确定,您必须调用它并查看它是否抛出 - 这也可能是伪造的。

所以你最好的选择可能是Function.prototype.toString,看看源的样子。如果您的 ES 实现支持。

在转译器中如何区分这些东西?

我认为没有任何转译器实现无原型的箭头和方法。类构造函数是否在被调用时抛出取决于转换的松散程度,但这无论如何都不是区分的好方法。
toString 也不起作用。

【讨论】:

  • 谢谢!。我刚刚在 v8 上试了一下,效果很好。 gist.github.com/boopathi/7c4adc4f4790f432838d 。但是,当我在方法上尝试它时它失败了。
  • 更新了要点。现在也支持检测生成器和方法。我希望我的假设是正确的。在代码 cmets 中提到了它们。
【解决方案2】:

你不能把前两种情况转译成这样:

var x = function x(i) {
  return i + 1;
};

function z(i) {
  return i + 1;
}

对于最后一个,你可以检查它是否在你调用它时抱怨它是否是一个类:

function isClass(instance){
  try{
    instance()
  }catch(e){
    return e.message === "Cannot call a class as a function";
  }
  return false;
}

但这显然会触发调用它的副作用,所以它在一般情况下不起作用。

【讨论】:

  • 呃,为什么这被否决了?它直接回答了这个问题。在没有解释的情况下开车投反对票是非常粗鲁的。
  • 我认为是因为在使用转译器之前您不会被转译,否则在本机浏览器中不会应用这种情况
  • @BarbuBarbu 问题的最后一部分是专门询问转译后的区分。
  • 哦,当然,对不起,我的错
猜你喜欢
  • 2020-05-07
  • 2019-01-17
  • 2022-12-06
  • 2019-04-12
  • 2017-03-13
  • 1970-01-01
  • 2019-02-24
  • 1970-01-01
相关资源
最近更新 更多