如何判断函数对象是否由箭头表达式创建?绑定场景需求
区分箭头函数与普通函数的替代方案(不用prototype属性)
既然你没办法依赖prototype属性来区分,我给你分享几个实用且可靠的方法,适配你需要处理对象内函数的场景:
方法1:通过函数的字符串表示判断(最常用)
箭头函数被toString()序列化后,要么以(开头(带参数的情况,比如(a,b) => {}),要么以标识符开头但包含=>(比如x => x);而普通函数(不管是函数声明还是表达式)都会以function开头。我们可以利用这个特征来写判断逻辑:
function isArrowFunction(fn) { if (typeof fn !== 'function') return false; const fnStr = fn.toString().trim(); // 处理被bind绑定过的函数:bind返回的函数字符串开头是"bound " if (fnStr.startsWith('bound ')) { const innerFnStr = fnStr.slice(6).trim(); return !innerFnStr.startsWith('function') && innerFnStr.includes('=>'); } // 普通情况:不是function开头,但包含=> return !fnStr.startsWith('function') && fnStr.includes('=>'); } // 测试用例 const arrow1 = () => 'hello'; const arrow2 = (x, y) => x + y; const regularFn = function() {}; const boundRegular = regularFn.bind({}); const boundArrow = arrow1.bind({}); console.log(isArrowFunction(arrow1)); // true console.log(isArrowFunction(arrow2)); // true console.log(isArrowFunction(regularFn)); // false console.log(isArrowFunction(boundRegular)); // false console.log(isArrowFunction(boundArrow)); // true
注意:如果有人刻意重写了函数的toString()方法,这个判断会失效,但在正常业务场景下,这种情况极少发生,所以这个方法的实用性很高。
方法2:利用箭头函数不能作为构造函数的特性
箭头函数没有[[Construct]]内部方法,所以不能用new关键字调用,调用会直接抛出错误;而普通函数(非生成器函数)可以被new调用。我们可以基于这个特性做判断:
function isArrowFunction(fn) { if (typeof fn !== 'function') return false; try { // 尝试用new调用函数 new fn(); // 能调用成功就说明不是箭头函数 return false; } catch (e) { // 箭头函数调用new会抛出"is not a constructor"的错误 return e.message.includes('is not a constructor'); } } // 测试用例 console.log(isArrowFunction(() => {})); // true console.log(isArrowFunction(function() {})); // false
注意:这个方法需要排除生成器函数(function*),因为生成器函数也不能被new调用。如果你的场景里有生成器函数,可以先通过fn.constructor.name === 'GeneratorFunction'做额外判断。
结合你的场景的建议
因为你需要把普通函数绑定到不同对象,而箭头函数的this是词法绑定无法被修改,所以识别出箭头函数后,你可以直接跳过绑定逻辑,或者根据业务需求做特殊处理(比如保留它的原始this上下文)。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

