【问题标题】:Accessing object properties with index gives undefined [closed]使用索引访问对象属性会给出未定义的 [关闭]
【发布时间】:2013-06-13 19:36:14
【问题描述】:

下面是一个包含对象的函数,我希望能够使用参数访问对象内的特定主体,即使用索引。

问题是当我尝试以这种方式访问​​属性时,我得到了

未定义

当控制台记录它时。我做错了什么?

moveLeftBtn.on('click', function(nr){
    var theBody = {
        bodies: {
            a: 'foo1',
            b: 'foo2',
            c: 'foo3'
        }
    };

    var newBody = theBody.bodies[1];    // temporarily hardcoded value instead of argument
    console.log(newBody);    // <-- undefined, why?

    return newBody;
});

编辑

如果我控制台日志 theBody.bodies 我可以看到它的值 (Object {a: Array[5], b: Array[5], c: Array[5]}),但是当我尝试使用 [1] 访问它的属性时,我得到了

未定义

(即使属性包含字符串)。

【问题讨论】:

  • theBody.bodies[nr] 是正确的。这称为“括号符号”。另请参阅:stackoverflow.com/questions/11922383/…。您编辑的代码工作正常:jsfiddle.net/q9ECP。请注意,括号表示法不是数组的特殊表示法,它是属性访问的一般工作方式。 如果标识符允许以数字开头,您可以使用arr.1 而不是arr[1] 访问数组。使用obj.fooobj['foo'] 访问普通对象的方式相同。
  • 规范中的相关部分:es5.github.io/#x11.2.1.
  • 如果您希望项目为 null,请删除 'null' 值周围的引号
  • @holyredbeard - 好的,现在theBody 赋值后缺少分号
  • 如果你看到(Object {a: Array[5], b: Array[5], c: Array[5]}),那么theBody.bodies'的属性是abc,而不是123。当然theBody.bodies[1] 会显示undefined。应该是theBody.bodies['a']。您想通过索引而不是名称来访问属性吗?这是不可能的(至少不是直接的)。

标签: javascript jquery arrays object properties


【解决方案1】:

我在您的代码中看到的唯一问题是您没有返回任何内容。改变 。 . .

var newBody = theBody.bodies[nr];

。 . .到 。 . .

return theBody.bodies[nr];

。 . .你应该很高兴。

编辑:哦,在定义theBody 之后,您还缺少;

【讨论】:

  • 谢谢!事情是,如果这样做,我会变得不确定。很奇怪!
  • 你传入了什么值?我已经在本地测试了它(在上面添加了 return 语句之后)并像这样调用函数:AccessBody(1); 正在返回对象中的文本(在 IE7 和 Firefox 中测试)。
  • 在定义 theBody 后也缺少一个冒号。 . .更新的答案。
  • “哦,在定义 theBody 之后,您还缺少 ;。” 幸运的是,分号是可选的;)问题不在于语法,而在于与数据结构。
  • 我将我的问题更新为我正在尝试使用的确切函数(现在是硬编码值,[1],而不是参数)。一样。 ://
【解决方案2】:

theBody.bodies 是一个具有三个属性的对象,分别名为 abc。您没有给它任何名为1 的属性。这就是theBody.bodies[1] 的值是undefined 的原因。如果您引用theBody.bodies['b'],您将找到您期望的属性之一,其值为'foo1'

听起来您只需要阅读 JavaScript 数组和对象以及它们是如何工作的。不要基于您可能在其他语言中使用过的“关联数组”之类的东西做出任何假设。 JavaScript 是一门自己的语言,有自己的做事方式,所以你只需要学习这些。

【讨论】:

    【解决方案3】:

    theBody.bodies 不是数组而是普通对象。通常你不能使用数字索引访问普通对象的字段。

    但您可以通过定义 theBody.bodies 对象来绕过它:

    var theBody = {
        bodies: {
            '0': 'foo1',
            '1': 'foo2',
            '2': 'foo3'
        }
    }
    

    以这种方式定义bodies,将有theBody.bodies[1] === 'foo2'

    如果您因任何原因无法更改 bodies,则可以对其进行处理并创建另一个对象,您可以使用数字索引访问这些字段 - 就像这样:

    var newBodies = [], i = 0, j;
    for (j in theBody.bodies) {
        newBodies.push(theBody.bodies[j]);
    }
    

    如果您 theBody.bodies 并非总是普通对象(例如某种类型的实例)而不是 for 循环,则应使用 $.eachfor 循环进行迭代,应使用 hasOwnProperty 检查.

    【讨论】:

    • “通常你不能使用数字索引访问普通对象的字段。” 好吧,数组也一样(因为数组也只是对象)。您只能访问存在的属性。 property name 可以是任意字符序列。在数组的情况下,数字属性名称以特殊方式处理。
    【解决方案4】:

    索引在 Firefox 上效果很好,但我不知道其他浏览器。您将不得不为索引检查添加更多逻辑。无论如何,您都不应该通过索引访问对象,因为属性的顺序可能会发生变化,您应该将它们视为映射或集合,而不是索引列表。

    我在这个例子的所有对象上附加了一个getByIndex() 函数。您可以创建自己的对象并将函数附加到它。

    这是我制作的一个 JSFiddle,可以满足您的需要:http://jsfiddle.net/zKrbr/4/

    Object.prototype.getByIndex = function (property, index) {
        var n = 0;
        if (this.hasOwnProperty(property)) {
            for (var prop in this[property]) {
                if (n == index) {
                    console.log('Found Match: '+prop+': '+this[property][prop]);
                    return this[property][prop];
                } else {
                    n++;
                }
            }
        }
        return undefined;
    }
    
    $('#moveLeft').on('click', function (nr) {
        var theBody = {
            bodies: {
                a: 'foo1',
                b: 'foo2',
                c: 'foo3'
            }
        };
        var index = parseInt($('#input').val());
        var currIndex = !isNaN(index) ? index : 0;
        var newBody = theBody.getByIndex('bodies', currIndex);
        $('#output').val(newBody);
    });
    
    <strong>Index:<strong>
    <input type="text" id="input" size="3"/>
    <input type="button" id="moveLeft" value="Move Left" />
    <input type="text" id="output" />
    

    【讨论】:

    • 您的Object.prototype.getByIndex 函数将无法可靠地工作,因为属性未排序。属性的迭代顺序可能因浏览器而异。见stackoverflow.com/q/280713/218196
    • 我明白,正如我所说:you should treat them as a map or a set as opposed to an indexed list。我只是提出一个建议。
    • 好的。我不会建议这样的事情。这太不可靠了。
    猜你喜欢
    • 2018-06-21
    • 2016-12-18
    • 2022-01-23
    • 2015-08-12
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    相关资源
    最近更新 更多