如何在不传递参数的情况下获取调用函数的父对象属性名?
解决方法:获取函数调用时的属性名
这问题我碰到过类似的,确实用arguments.callee.name拿不到属性名,因为它返回的是函数本身的名字。给你几个不用传参就能实现的方案:
方案1:闭包绑定属性名(最直观)
我们可以写一个工厂函数,每次创建对应菜单项的处理函数,通过闭包把属性名保存下来。这样每个菜单项的函数都能记住自己对应的名称:
// 原来的getMenu逻辑可以整合到这里 function createMenuHandler(itemName) { return function() { console.log(itemName); // 这里放原来getMenu里的do something逻辑 }; } var menu = { pizza: createMenuHandler('pizza'), burger: createMenuHandler('burger') }; menu.pizza(); // 打印 'pizza' menu.burger(); // 打印 'burger'
这个方案的好处是简单易懂,每个函数实例都独立保留了对应的名称,调用时直接就能用,完全不用传参。
方案2:ES6 Proxy 动态拦截(适合动态场景)
如果你的menu对象后面可能会动态添加新的菜单项,用Proxy会更灵活,不用每次都手动创建新的处理函数:
// 定义基础的menu结构,里面的函数可以留空或者放通用逻辑 const baseMenu = { pizza: function() {}, burger: function() {} }; var menu = new Proxy(baseMenu, { get(target, prop) { // 每次访问属性时,返回一个绑定了当前属性名的函数 return function() { console.log(prop); // 执行原来getMenu的逻辑,比如可以调用target[prop]()来执行基础函数 target[prop](); }; } }); menu.pizza(); // 打印 'pizza' menu.burger(); // 打印 'burger' // 后面加新属性也自动生效 menu.fries = function() {}; menu.fries(); // 打印 'fries'
Proxy的get陷阱会在你访问menu的任何属性时触发,我们在这里返回一个新函数,这个函数能直接拿到当前的属性名prop,完美解决你的需求。
方案3:通过遍历对象查找(有局限性)
这个方法不推荐,但可以作为思路参考:通过this指向的menu对象,遍历它的所有属性,找到当前函数对应的属性名。不过要注意,如果多个属性引用同一个函数实例(比如你的场景里pizza和burger都指向getMenu),这个方法会返回第一个匹配的属性名,导致调用burger()也打印pizza,所以只适合每个属性对应唯一函数实例的场景:
function getMenu() { // 遍历menu的所有键,找到当前函数对应的那个 const propName = Object.keys(menu).find(key => menu[key] === this); console.log(propName); } var menu = { pizza: getMenu, burger: getMenu }; // 这里调用menu.burger()会打印'pizza',因为find返回第一个匹配的key,所以这个方案不适合你的场景
总结一下,方案1和方案2都是靠谱的选择,方案1适合静态的menu结构,方案2适合动态添加属性的场景,根据你的需求选就行~
内容的提问来源于stack exchange,提问作者shadow
相关产品推荐
相关产品推荐

