如何区分箭头函数、类和普通函数?

IT技术 javascript ecmascript-6 arrow-functions
2021-02-22 09:38:23

如何使用 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?

2个回答

我如何区分 ES6 中的这些东西?

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

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

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

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

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

更新了要点。现在也支持检测生成器和方法。我希望我的假设是正确的。在代码注释中提到它们。
2021-04-25 09:38:23
谢谢!。我刚刚在 v8 上试了一下,效果很好。gist.github.com/boopathi/7c4adc4f4790f432838d但是当我尝试方法时它失败了。
2021-05-06 09:38:23

您不能将前两种情况转译为:

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;
}

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

呃,为什么这被否决了?它直接回答了问题。在没有解释的情况下直接投票否决某些内容是非常粗鲁的。
2021-04-30 09:38:23
@BarbuBarbu 问题的最后一部分是专门询问转译后的区分。
2021-05-04 09:38:23
我认为因为在使用转译器之前您不会被转译,否则在本机浏览器中将不会应用这种情况
2021-05-07 09:38:23
哦,当然,对不起,我的错
2021-05-16 09:38:23