我正在创建一个将对象作为参数的函数,并使用存储在该对象中的数据执行操作。我想做的一些涉及该对象的功能。我想将它们中的大多数绑定到各种对象,但这对于使用fat arrow syntax创建的任何函数都不起作用。所以,我想做些与他们不同的事情。我怎么能分开呢?
注意:我知道正常的函数有一个原型但是由胖箭头语法制作的函数没有,但是我不能使用它,因为用method syntax创建的函数也没有。有一个原型,但它们可以绑定,所以我想像其他功能一样对待它们。
答案 0 :(得分:3)
您可以使用Function#toString()检查函数的源代码,看看它是否被定义为箭头函数。
const foo = () => {};
const fooStr = Function.prototype.toString.call(foo);
const isArrow = fooStr.includes(') => {');
请注意,上述实现对于大多数用例来说可能过于天真,因为它有一些误报和否定。对于初学者,如果isArrow
是包含箭头功能的正常函数(或者在其中的任何位置具有该特定字符串,例如注释等),则true
将为foo
。
我们可以通过尝试特别匹配函数定义的头来改进这一点。下面,我通过搜索大括号{
的第一次出现来做到这一点,这对于箭头和非箭头函数都是通用的。
const foo = () => {};
const fooStr = Function.prototype.toString.call(foo);
const curlyIndex = fooStr.indexOf('{');
const head = fooStr.substring(0, Math.max(curlyIndex, 0));
const isArrow = head.endsWith(') => {');
不幸的是,对于我们来说,圆形和花括号实际上都是箭头功能的可选项,它们甚至不需要任何空格。理想情况下,我们需要在foo
为x=>x
时才有效的内容。
const foo = x=>x;
const fooStr = Function.prototype.toString.call(foo);
const curlyIndex = fooStr.indexOf('{');
let isArrow = true;
if (curlyIndex >= 0) {
const head = fooStr.substring(0, curlyIndex);
isArrow = head.replace(/\s/g, '').endsWith('=>{');
}
上述实现方式中等,但当foo
类似于x => x + '{'
时,它仍然存在误报。还有其他陷阱,所以不要认为它在那里结束。字符串分析很难,特别是当语法是可选的时。
您可以使用Esprima,Acorn或Cherow这样的库来解析字符串,并更完美地识别代码是否为箭头函数,但这可能是过度的你。
为了让您了解它的外观,下面是我输入空箭头功能时Cherow demo的输出:
{
"type": "Program",
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"expression": {
"type": "ArrowFunctionExpression",
"body": {
"type": "BlockStatement",
"body": []
},
"params": [],
"id": null,
"async": false,
"generator": false,
"expression": false
}
}
]
}