如何在现代JavaScript中定义真正无名称的函数?
如何在JavaScript中创建真正无名称的匿名函数
在ES6及之后的版本中,JavaScript引擎会自动为赋值给变量的函数表达式(包括箭头函数)赋予name属性,这就是你看到foo.name输出变量名的原因。要创建真正无名称(即name属性为空字符串)的函数,有两种实用方案:
方案1:手动重置函数的name属性
函数的name属性默认是可配置的,你可以通过Object.defineProperty强制将其设置为空字符串,这样打印时就不会显示函数名称。
针对你的curry函数,只需在定义curried后添加一行代码即可:
function curry(fn, ...init_args) { typecheck('curry', fn, 'function'); var len = fn.length; return function() { var args = init_args.slice(); const curried = (...more_args) => { args = args.concat(more_args); if (args.length >= len) { return fn.apply(this, args); } else { return curried; } }; // 重置name属性为空字符串 Object.defineProperty(curried, 'name', { value: '' }); return curried(...arguments); }; }
修改后,curried函数的name就会变成空值,你的Scheme解释器打印时就会显示#<procedure>而非#<procedure:curried>。
方案2:使用Function构造函数创建匿名函数
Function构造函数创建的函数默认name属性为空字符串,不过这种方式需要将函数体以字符串形式传入,对于依赖闭包变量(比如你的args、fn、len)的场景不太方便,但如果是简单函数可以使用:
const anonFn = new Function('more_args', ` args = args.concat(more_args); if (args.length >= len) { return fn.apply(this, args); } else { return anonFn; } `);
不过由于你的curry函数依赖闭包中的变量,方案1会更直接且易于维护。
验证效果
修改后运行你的Scheme代码:
(define (sum a b c) (+ a b c)) (define add1 (curry sum)) (print (add1 2)) ;; ==> #<procedure>
就能得到你想要的输出了。
内容的提问来源于stack exchange,提问作者jcubic
相关产品推荐
相关产品推荐

