【问题标题】:Function Scope issue when declaring an array of objects声明对象数组时的函数范围问题
【发布时间】:2013-10-22 19:23:04
【问题描述】:

这是我目前拥有的代码,正在发生的一个问题是我不能使用test(),因为presets[index].namevalue 在它们的函数范围之外是不可见的,我应该如何在其中声明我的对象数组全局范围以便我能够在其他函数中访问这两个变量?

var presets = [];
var index;

function CreatePresetArray(AMib, AVar) {
    var parentpresetStringOID = snmp.getOID(AMib, AVar);
    var presetStringOID = parentpresetStringOID;
    parentpresetStringOID = parentpresetStringOID.substring(0, parentpresetStringOID.length - 2);
    log.error("parentpresetStringOID is " + parentpresetStringOID);

    var presetswitches = {};

    for (var i = 1; i < 41; i++) {
        presets.push(presetswitches);
        try {
            log.error("presetStringOID before getNextVB= " + presetStringOID);
            vb = snmp.getNextVB(presetStringOID);
            presetStringOID = vb.oid;
            log.error("presetStringOID  after getnextVB= " + presetStringOID);

            var presetStringVal = snmp.get(presetStringOID);

            log.error("presetStringVal= " + presetStringVal);

            index = i - 1;

            presets[index].name = presetStringOID;
            presets[index].value = presetStringVal;
            log.error("preset array's OID at position [" + index + "]     is" + presets[index].name + " and the value stored is " + presets[index].value);

            //log.error("presets Array value ["+index+"] =     "+presets[index].configs);

            if (presetStringOID.indexOf(parentpresetStringOID) != 0) {
                break;
            }

        } catch (ie) {
            log.error("couldn't load preset array " + index);
        };
    };
}

CreatePresetArray(presetMib, "presetString");

function test() {
    for (i = 1; i < 41; i++) {
        log.error("test" + presets[index].name + "        " + presets[index].value);
    };
}
test();

【问题讨论】:

  • 请粘贴您提到的代码
  • 慢慢来,将每个代码行缩进至少 4 个字符……这样就可以了
  • 您也可以发布指向 jsfiddle.net/ 或 codepen.io 的链接
  • 你在哪里以及如何准确地调用函数CreatePresetArray
  • 这意味着“如果你根本不调用它,那将是问题”:-)

标签: javascript arrays function object scope


【解决方案1】:

函数test 中的for 循环迭代i,但在循环内使用index。也许你打算使用

for (i = 0; i < 40; i++) { // 1 lower as you were using `index = i - 1` before
    log.error("test" + presets[i].name + "        " + presets[i].value);
}

重新编写了您的代码。我不认为我通过改变获得了那么多。如果这不能解决您的问题,请考虑:catch 是否每次迭代都会发生?问题实际上来自仅在此处可见的不同方法吗?另外,在调试时考虑记录整个 presets Array 以查看它的样子。

var presets = [];

function CreatePresetArray(AMib, AVar) {
    var parentPresetOID, presetOID, presetValue, preset, vb, i;
    parentPresetOID = snmp.getOID(AMib, AVar);
    presetOID = parentPresetOID; // initial
    parentPresetOID = parentPresetOID.substring(0, parentPresetOID.length - 2);

    log.error("parentPresetOID is " + parentPresetOID);
    presets = []; // empty array in case not already empty
    for (i = 0; i < 40; ++i) {
        try {
            preset = {}; // new object
            // new presetOID
            vb = snmp.getNextVB(presetOID);
            presetOID = vb.oid;
            log.error("presetOID  after getnextVB= " + presetOID);
            // new value
            presetValue = snmp.get(presetOID);
            log.error("presetValue= " + presetValue);
            // append data to object
            preset.name = presetOID;
            preset.value = presetValue;
            // append object to array
            presets.push(preset);
            // more logging
            log.error(
                "preset array's OID at position [" + i + "]" +
                "     is" + presets[i].name + " and " +
                "the value stored is " + presets[i].value
            );
            if (presetOID.indexOf(parentPresetOID) !== 0) {
                break;
            }
        } catch (ie) {
            log.error("couldn't load preset array " + i);
            if (presets.length !== i + 1) { // enter dummy for failed item
                presets.push(null);
            }
        }
    }
}

【讨论】:

  • 谢谢,我试过用i代替index,但还是看不到数组预设的.name和.value,因为它只是在函数createpresetArray中声明的
  • 不,不是。您在函数之前声明了它。这应该足够了,如果你在调用test()之前调用函数CreatePresetArray
  • 我在调用 test() 之前尝试调用 createpresetArray,当我编译时,错误说无法从未定义中读取属性“名称”
  • 请用我编辑的代码再试一次,错误可能只出现在最后一次迭代中
  • 谢谢你,Paul,我用你的代码试过了,但还是不行,它给出了和以前一样的错误。
【解决方案2】:

立即想到两个选项:

  • 您可以将预设数组作为参数传递给 test()。
  • 您可以将 CreatePresetArray() 和 test() 放在一个包装器函数中,并在包装​​器顶部声明预设数组。这将使他们都可以访问该变量。

如果可以避免,通常认为声明全局变量是错误的形式。污染命名空间。

【讨论】:

  • presetsvard 在 CreatePresetArray 声明之前。
  • 事情是根据我被告知的,我想创建两个不同的函数,第一个是 createpresetArray,第二个是假设能够引用我创建的数组通过给它一个索引,这意味着这两个函数不应该被包装在一个包装器中,并且我还被告知引用我创建的数组的第二个函数不应该将数组作为参数,而只是一个索引。
猜你喜欢
  • 1970-01-01
  • 2011-06-12
  • 2015-04-12
  • 2015-03-14
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多