Javascript 变量声明条件语法
我正在寻找一些很棒的d3.js,这时我看到了如下内容:Javascript 变量声明条件语法,javascript,variables,syntax,d3.js,Javascript,Variables,Syntax,D3.js,我正在寻找一些很棒的d3.js,这时我看到了如下内容: var links = [ {source: "test1", target: "test2"}, {source: "test1", target: "test3"}, {source: "test2", target: "test3"}, {source: "test3", target: "test4"} ]; var nodes = {}; // Compute the distinct nodes from t
var links = [
{source: "test1", target: "test2"},
{source: "test1", target: "test3"},
{source: "test2", target: "test3"},
{source: "test3", target: "test4"}
];
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});
我没有立即了解var节点是如何声明的
我的第一个猜测是把它翻译成:
links.forEach(function(link) {
if(link.source != nodes[link.source]){
nodes[link.source] = {name: link.source};
}
if(link.target != nodes[link.target]){
nodes[link.target] = {name: link.target};
}
});
但是链接不再被绘制
这两种方法有什么区别
初始语法的意义是什么?它只是一种快捷方式还是提高了性能
在这种情况下,是否有最佳实践可遵循
编辑
所以如果我试着完全理解
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
我哪里错了?第2点对我来说似乎很奇怪。示例中使用的代码只是一个语法快捷方式。相当于
links.forEach(function(link) {
if(nodes[link.source]) { // we already know about the source of this link
link.source = nodes[link.source];
} else { // we haven't seen this source before, create a new node for it
nodes[link.source] = {name: link.source};
link.source = nodes[link.source];
}
if(nodes[link.target]) { // we already know about the target of this link
link.target = nodes[link.target];
} else { // we haven't seen this target before, create a new node for it
nodes[link.target] = {name: link.target};
link.target = nodes[link.target];
}
});
所有这些都是必要的,因为节点只是通过链接隐式声明的——也就是说,没有节点列表,它只是通过遍历链接和“获取”源和目标来组装的。这是存储在节点中的内容
——它是从节点ID(从链接)到表示节点的对象的映射
上面的代码通过为看不见的节点(即映射中不存在的节点)创建新对象并插入相应的映射来同时填充此映射。然后更新链接的源和目标,以指向这些对象(稍后将由“力”布局操作以设置其位置),而不是原始数据中引用的节点ID
编辑:您编辑的解释是正确的。这基本上就是正在发生的事情
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
可翻译为:
if(!nodes[link.source]) {
nodes[link.source] = {name: link.source};
}
link.source = nodes[link.source];
(与link.target相同)
因此:
将转变为:
links = [
{source: { name: "test1" }, target: { name: "test2" }},
{source: { name: "test1" }, target: { name: "test3" }},
{source: { name: "test2" }, target: { name: "test3" }},
{source: { name: "test3" }, target: { name: "test4" }}
];
和节点将等于:
nodes = {
"test1": { name: "test1" },
"test2": { name: "test2" },
"test3": { name: "test3" },
"test4": { name: "test4" },
}
我的理解
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
是,如果节点[link.source]
不存在
然后只需执行link.source=nodes[link.source]={name:link.source}
外部检查如果(link.source!=节点[link.source]){
在这种情况下实际上是不必要的(并且在原始代码中不存在)。它是隐式的(link.source
最终应该等于节点[link.source]
),并且将阻止设置link.source=节点[link.source]
重复值的次数不止一次。这是一个映射--不确定如何在其中获取重复值?不,它不是隐式的。如果存在重复值,原始代码将执行多个赋值。我说的是链接,其中源代码等于测试1
多次,这将继续执行lt inlink.source=nodes[link.source];
如果我删除外部检查,会多次调用。原始代码是一个快捷代码,因此很明显,扩展它可以有许多不同的方式,如果需要优化,可能会产生不同的代码(结果当然必须保持完全相同).Ah,但是link
在循环中,因此每次都会指向不同的对象。如果link
是同一个对象,则此代码块不会执行多次。