对象成员并在JS中访问它们

object members and accessing them in JS

本文关键字:访问 JS 成员 对象      更新时间:2023-09-26

我对JavaScript非常陌生,正在尝试使用JS加载数据库,以基于数据库绘制一些散点图。我想加载两个数据库:一个数据库有我想绘制的信息,但也有每条线的标识符,第二个数据库有一些基于ID的分组或分类信息。想法是使用第二个DB中的分类来为散点图中的点着色。每个ID在第一个DB中可以有多行。以下是我如何加载数据库:

d3.csv('../data/db1.csv', function(data) {
    data.forEach(function(d) {
        d.x = +d.x;
        d.y = +d.y;
        d.ID = d.ID;
        d3.csv('../data/db2.csv', function(p) {
            p.forEach(function(pp) {
                var group = pp.group;
                var id = pp.id;
                if(id === d.ID){
                    d.group = group;
                }
            });
        };
        console.log("d", d);
        console.log("d.group", d.group);
    });
});

现在问题出现在两行console.log上,第一行返回:

d Object { x: 0.0, y: 0.0, ID: "000", group: 0, ...}

但第二行返回:

d.group undefined

我不明白的是,为什么对象d具有group的正确值,但实际上并没有定义d.groupd.group不是应该指向dgroup成员吗?

更新:

根据下面的建议,我尝试了一些其他版本。第一:

d3.csv(...
    data.forEach(...
        ...
        d3.csv(...
            ...
            //do the post processing here
        });
     });
     data.forEach(function(d){
         console.log('d', d);
         console.log('d.something', d.something);
     });
});

以及:

d3.csv(...
    data.forEach(...
        ...
        d3.csv(...
            ...
        });
     });
     data.forEach(function(d){
         //do the post processing here
     });
     data.forEach(function(d){
         console.log('d', d);
         console.log('d.something', d.something);
     });
});

在这两个问题中,我都得到了相同的问题,带有console.log(d)的行打印得很好,并且带有d.something,因为它应该是后处理出来的。但与CCD_ 9的线显示为CCD_。

这不仅仅是console.log,我试着在FireFox的inspect元素中调试它,并添加了一些手表,那里也发生了同样的情况。

您面临的问题是javascript的异步特性及其提供的运行到完成保证。

长话短说,因为加载CSV文件是一个异步操作,javascript将在运行处理CSV文件的回调函数之前完全运行父函数。因此,您只有在组数据加载后才能访问它(只有在执行回调时才能保证)。因此,即使console.log函数在视觉上加载组之后出现,它们也会在加载组数据之前执行。

如果将console.log调用移到最内部的函数中,它们都将工作。

你可以在MDN上阅读更多关于这方面的内容,这里有另一篇很好的文章