【问题标题】:Javascript method and local variableJavascript方法和局部变量
【发布时间】:2016-10-11 08:02:33
【问题描述】:

我一直在互联网上搜索,但找不到合适的词来搜索,所以我在这里再次向你们所有 Javascript 的前辈提问。 下面的代码取自答案on these question 我真的不明白方法或功能是如何工作的。

var list = [{id: 1,title: 'home',parent: null},{id: 2,title: 'about',parent: null},{id: 3,title: 'team',parent: 2},{id: 4,title: 'company',parent: 2} ];
function treeify(list) {
     var treeList = [];
     var lookup = {};
     list.forEach(function(obj) {
          obj['children'] = [];
          lookup[obj['id']] = obj;
     });
     console.log(lookup); // [problem number 1]

     list.forEach(function(obj) {
          if (obj['parent'] != null) {
               lookup[obj['parent']]['children'].push(obj);
          } else {
               treeList.push(obj);
          }
     });

     console.log(treeList); // [problem number 2]
};

treeify(list);

关于第一个问题:

这导致一个对象在每个父对象上都有一个子对象,据推测我认为,父对象此时应该有一个空数组 children。它是如何工作的?请赐教。

关于问题 2

treeList 已经形成了层次结构树。它是怎么发生的?它甚至没有将查找变量推送到 treeList 变量?它只推送具有等于 null 的父级(即根父级)的 obj。

希望得到您的答复。 如果您知道任何可以帮助我理解 javascript 的博客、文章等,请不要犹豫,在您的答案中添加链接。 非常感谢!

【问题讨论】:

  • 您的问题 #1 是您在 console.log 中看到的并不是那个时间点查找状态的真实图片...尝试console.log(JSON.parse(JSON.stringify(lookup))); 查看“快照”在那一点上查找
  • 为什么不是真的?你能再解释一下吗?
  • 因为console.log输出对象,你展开那个对象,它显示的是当前状态,而不是记录对象的状态

标签: javascript


【解决方案1】:
var list = [
     {id: 1,title: 'home',parent: null},
     {id: 2,title: 'about',parent: null},
     {id: 3,title: 'team',parent: 2},
     {id: 4,title: 'company',parent: 2} 
];

treeify(list);


function treeify(list) {

     var treeList = []; //local array
     var lookup = {}; //local object

     // iterate over each element in list array
     list.forEach(function(obj) {

          // add a children property to each element in the array
          // in this case the children property is an array
          obj['children'] = [];

          // obj['id'] returns 1,2,3,4
          // lookup is an object so we use the id of each element in the list array as a key
          // first iteration adds key : 1 and value {id:1, title: 'home', parent: null, children: [] }
          // second iteration adds key : 2 and value {id:2, title: 'about', parent: null, children: [] }
          // ...
          lookup[obj['id']] = obj;
     });

     /*
          console.log(lookup) should output
          {
               1: {id: 1,title: 'home', parent: null, children: []},
               2: {id: 2,title: 'about', parent: null, children: []},
               3: {id: 3,title: 'team', parent: 2, children: []},
               4: {id: 4,title: 'company', parent: 2, children: []} 
          }

          however, if you run the code the lookup object gets modifyed in 
          the lines below (lookup[obj['parent']]['children'].push(obj);),
          therefore, some items in the lookup object will have children elements in its child array
     */
     console.log(lookup); // [problem number 1]

     list.forEach(function(obj) {
          if (obj['parent'] != null) {
               // this line modifyes the lookup object at runtime
               // obj has a parent, so we add it to the corresponding parents children array using the id
               lookup[obj['parent']]['children'].push(obj);
          } else {
               //only adds an element to the treelist array if its a parent element
               treeList.push(obj);
          }
     });

     console.log(treeList);
};

【讨论】:

  • treeList 对象是对来自lookup 的对象的引用。为了说明这一点,我们可以在最后一个 forEach 循环之后添加一个 lookup['4'].title = 'random title'; 并查看 treeList 对象被修改。
  • 对不起,我还是 javascript 的菜鸟。所以你的意思是这就是你在javascript中引用的方式?特别是在这一行代码 lookup[obj['id']] = obj ?我以为它只是在复制 obj 的值。
  • 其实我想这就是你一开始没看懂代码的原因。对象没有被复制,只是被引用。 This question 对此有有趣的见解。
  • 哈哈。现在我在嘲笑自己。现在我明白了。谢谢@damienc 的链接。
  • this bin,它突出了这种机制。
【解决方案2】:

问题 1:
你的假设是对的,但问题是console.log 正在记录一个引用。因为lookup 对象稍后会更改,您会看到这些更改。 read more

function treeify(list) {
    var treeList = [];
    var lookup = {};
    list.forEach(function(obj) {
        obj['children'] = [];
        lookup[obj['id']] = obj;
    });
    console.log(lookup); // Now you're right
};

问题 2:
lookup 中的所有对象都引用了list

lookup[obj['id']] = obj;

childrens 在这里得到更改。

lookup[obj['parent']]['children'].push(obj);

treeList 中的引用也是相同的。

【讨论】:

  • treeList 包含层次结构的根元素,而根元素又包含其子数组中的子元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多