为何JS直接定义的对象方法有名称、动态添加的方法为匿名函数?
JavaScript函数
name属性的推断规则差异说明 这个现象本质是ES6中函数名称自动推断规则的生效时机差异导致的:
- 直接在对象字面量中定义的属性方法,函数创建时就直接绑定到了对应的属性名上,会触发引擎的名称推断,将属性名作为函数的
name属性值 - 先创建匿名函数再作为参数传递、后续才赋值给对象属性的场景,函数创建时没有可推断的名称标识,后续赋值也不会修改已生成的
name属性
对应代码场景拆解
- 初始化阶段的方法有名称
你在Calculator构造函数中定义this.methods对象时,+、-对应的箭头函数是在对象字面量初始化时直接作为属性值创建的:
this.methods = { "-": (a, b) => a - b, "+": (a, b) => a + b, };
此时引擎会直接把属性名+、-推断为对应函数的name值,所以访问powerCalc.methods["+"].name能拿到值。
- 动态新增的方法无名称
你调用addMethod时传入的箭头函数,是先作为独立的函数表达式创建完成后才作为参数传递的:
powerCalc.addMethod("*", (a, b) => a * b);
这个箭头函数创建时没有直接绑定到某个具名的变量/属性上,引擎无法推断名称,生成的函数实例name默认是空字符串。后续在addMethod内将它赋值给this.methods[operator]是函数创建完成后的二次赋值,不会触发名称推断,也不会修改已经生成的name属性,所以访问powerCalc.methods["*"].name返回空。
兼容处理方案
如果需要动态新增的方法也有对应运算符的name属性,可以在addMethod中手动修改函数的name:
this.addMethod = (operator, method) => { Object.defineProperty(method, 'name', { value: operator, configurable: true }); this.methods[operator] = method; }
内容的提问来源于stack exchange,提问作者VL4D
相关产品推荐
相关产品推荐

