繁体   English   中英

我可以在不将其作为参数传递的情况下,使一个全局函数访问另一全局函数的局部变量吗?

[英]Can I give one global function access to another global function's local vars, without passing them as parameters?

免责声明:这篇荒谬的篇幅更多地与学习如何更优雅地编写代码有关,而不是解决一个实际问题,以防万一这是您能否坚持到底的重要因素!

我的脚本处理角色扮演游戏的属性。 每个属性都有三个元素:内部使用的ID( attrID ),游戏中显示的专有名称( attrName )和属性的值( attrVal )。

我已经声明了一个全局函数getAttrName(attrID) ,该函数接受属性ID并通过全局查找表返回适当的显示名称:

const ATTRNAMES = {id1: "Strength", id2: "Dexterity", id3: "Health"}
const getAttrName = id => ATTRNAMES[id]

console.log(getAttrName("id1"))
 // > Strength

现在,必须通过内部API方法getAttrs(idArray)异步检索属性 ,该方法将请求的值作为{attrID: attrVal}对的列表传递给回调函数:

getAttrs(["id1", "id2", "id3"], attrList => {
    // the attributes' IDs, values and display names are accessible:
    _.each(attrList, (v, k) => {
        [attrID, attrVal, attrName] = [k, v, getAttrName(k)]
        console.log([attrID, attrVal, attrName])
    })
})
 // > ["id1", 3, "Strength"]
 // > ["id2", 4, "Dexterity"]
 // > ["id3", 10, "Health"]

自定义属性会带来复杂性, 自定义属性可以由玩家在游戏运行时动态创建。 全局查找表不能包含这些名称,因此会将它们存储在ID为<id>_name形式的“伙伴”属性中。 仅显示包含标准和自定义属性的典型attrList (由getAttrs()传递给回调函数getAttrs()更容易:

{        
// STANDARD attributes, in the form {attrID: attrVal}:
    id1: 3,
    id2: 4,
    id3: 10,                  // ... for Strength 3, Dexterity 2, Health: 10.
// CUSTOM attributes, each with a partner <ID>_name attribute:
    id4: 1,
    id4_name: "Coding",
    id5: 0,
    id5_name: "Brevity"       // ... for Coding: 1, Brevity: 0.
}

(重要的是:我在第三方API的范围内工作,并且无法控制属性列表的结构或自定义属性的存储方式。)

问题

我希望getAttrName()在回调函数中可互换地处理自定义和标准属性。 为此,它需要访问attrList ,其范围是回调函数。

废弃的解决方案#1:也可以在回调函数中声明getAttrName()

getAttrs(["id1", "id2", "id3", "id4", "id5"], attrList => {
    const getAttrName = id => ATTRNAMES[id] || attrList[`${id}_name`]
          /* returns from the global lookup ATTRNAMES if it exists,
                      OR from the <ID>_name attribute in attrList if not. */

    // as before, the attributes' elements are accessible, whether custom or standard
    _.each(attrList, (v, k) => { 
          // ... after filtering out the "<ID>_name" partners, which are also passed
        if (!k.includes("_name")) {
            [attrID, attrVal, attrName] = [k, v, getAttrName(k)]
            console.log([attrID, attrVal, attrName])
        }
    })
})
 // > ["id1", 3, "Strength"]
 // > ["id2", 4, "Dexterity"]
 // > ["id3", 10, "Health"]
 // > ["id4", 1, "Coding"]
 // > ["id5", 0, "Brevity"]

这几乎是我想要的行为 ...但是, getAttrs() API方法在我的代码中被多次使用,即使在一行中,它也让我一次又一次地声明相同的函数(实际上,它对我表示感谢,足以花一个小时写这个问题并将其格式化为大家;))

废弃的解决方案#2:我还可以添加第二个参数来getAttrName ,并用它来传递attrList到它的时候,它被称为。 我确实不愿意这样做是出于多种原因,但是启发我写所有这些内容的一个原因是,这样做使我感到笨拙(特别是因为getAttrName调用attrList时,传递attrList不会是必要的),我正在努力提高自己的编码技能,并且我很感兴趣并且好奇地听到我没有考虑过的第三个解决方案!

问题

有什么办法留住全球范围getAttrName函数声明, 给它访问之前声明的局部变量getAttrName被调用, 不必申报getAttrName多次或给它更多的参数呢?

您可以创建一个函数创建函数:

const makeGetAttrName = list => id => list[id]

const globalGetAttrName = makeGetAttrName(ATTRNAMES);

然后在回调中,您可以创建本地版本:

    const localGetAttrName = makeGetAttrName(attrList);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM