JavaScript使用字符串值作为对象的引用(不使用eval())

时间:2014-01-04 07:00:17

标签: javascript arrays variables object

我创建了一堆具有“name”,“type”,“positionX”,“positionY”等属性的对象(节点)。它们还有一个数组“连接”,它从空开始。在创建Object时,我还将它存储在Array objectList中,这样我就可以在循环中轻松遍历它们。

//Pseudo-Object
function Node (n,t,x,y) {
    this.name = n;
    this.type = t;
    this.connections = new Array();
    this.positionX = 0;
    this.positionY = 0;
    tempArrayPosition = nodeList.length;
    nodeList[tempArrayPosition] = this;
}

//Create node list
var nodeList = new Array();

//Create some nodes
var node1 = new Node("node.foo", "io", 40, 60);
var node2 = new Node("node.bar", "fw", 10, 10);
var node3 = new node("node.narf", "mcu", 20, 100);

遍历nodeList数组可以正常工作。我可以使用此代码来显示一个节点Object有多少个连接:

//Create some connections (will later be done by a method of Node)
node2.connections[node2.connections.length] = "node1";
node2.connections[node2.connections.length] = "node3";
node3.connections[node3.connections.length] = "node2";

console.log("Show number of connections between nodes:");
for (var i = nodeList.length - 1; i >= 0; i--) {
    console.log("Node " + nodeList[i].name + " has " + nodeList[i].connections.length + " connections to other nodes.");
};

现在,当我想详细显示连接时问题就出现了。 .connections数组由变量/对象名称组成。但我似乎无法使用它们来访问这些对象。

我像这样扩展循环:

console.log("Show number of connections between nodes:");
for (var i = nodeList.length - 1; i >= 0; i--) {
    console.log("Node " + nodeList[i].name + " has " + nodeList[i].connections.length + " connections to other nodes.");
    if (nodeList[i].connections.length > 0) {
        for (var j = nodeList[i].connections.length - 1; j >= 0; j--) {
            var tempObjectName = nodeList[i].connections[j];
            console.log(nodeList[i].name    + " - " + tempObjectName.name);
        }
    }
};

它返回“undefined” - 因为很明显它不会将“node1”等视为对象引用而是字符串。我知道我可以使用

var tempObjectName = eval(nodeList[i].connections[j]);

但即使我对JS的经验很少,我也看到“eval()是邪恶的,不要使用它”十几次......

所以我的问题是:

  • a)有一种简单而“安全”(非评估)的方式让JS对待它 数组中的字符串作为对var / object的引用 名称?
  • b)我尝试的方式是否存在根本性缺陷 组织/管理我创建的对象(使用对象数组)?
  • b.2)如果是这样,会有什么更优雅的方式?

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

您应该存储对象本身而不是其名称:

node2.connections.push(node1);

如果你不喜欢这个建议,试试这个:

var tempObjectName = window[nodeList[i].connections[j]];

如果在全局范围内宣布node1node2nodeN,这将是一种肮脏的做法。

答案 1 :(得分:1)

你的tempObjectName是一个字符串,而不是一个对象。检查代码中的typeof tempObjectName。 如果您打印tempObjectName,它会为您提供所需的结果。

for (var i = nodeList.length - 1; i >= 0; i--) {
    console.log("Node " + nodeList[i].name + " has " + nodeList[i].connections.length + " connections to other nodes.");
    if (nodeList[i].connections.length > 0) {
        for (var j = nodeList[i].connections.length - 1; j >= 0; j--) {
            var tempObjectName = nodeList[i].connections[j];
            console.log(typeof tempObjectName);
            console.log(nodeList[i].name    + " - " + tempObjectName);
        }
    }
};

这里是jsFiddle:http://jsfiddle.net/ashishanexpert/y9ZEW/