当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - Array being reset to undefined after adding items to it

问题描述:

I am trying to construct a hierarchy (tree structure) using JavaScript. For that, I wrote a Node class that represents a node in the tree. When I retrieve the data from the database, it's all being retrieved properly (i.e: the root node has the ParentId as null, it has 3 children that point to it as the parent, and the descendant nodes are set up properly as well...). But when I try to map them to my JavaScript model, the Children property of the root node is ending up being undefined. I do not know how that could be posible even though during runtime, when I output the contents of the Children property in the console I can see the children nodes being added to it. Here's my code:

var Node = function (obj) {

var self = this;

var isDefined = obj != undefined;

self.hasChildren = function () {

return self.Children.length > 0;

};

self.hasParent = function () {

var p = self.ParentId;

return !(p == null || p == undefined || p == 0);

};

self.addChildren = function (objArray) {

if (!$.isArray(self.Children)) {

self.Children = [];

}

for (var i = 0; i < objArray.length; i++) {

self.addChild(objArray[i]);

}

};

self.addChild = function (obj) {

if (obj instanceof Node) {

self.Children.push(obj);

} else {

var n = new Node(obj);

self.Children.push(n);

}

};

self.removeChild = function (n) {

var index = self.Children.indexOf(n);

if (index > -1) {

self.Children.splice(index, 1);

}

};

self.Id = isDefined ? obj.Id : null;

self.ParentId = isDefined ? obj.ParentId : null;

self.Name = isDefined ? obj.Name : '';

self.Children = isDefined ? self.addChildren(obj.Children) : [];

self.TypeId = isDefined ? obj.TypeId : null;

};

The way I thought about the addChildren method, is that I would pass the raw JSON object coming from the server into the constructor of the Node object and then in case it has any children (which essentially have the same properties as the parent), addChildren will be called which will in turn create a new Node for each element. Eventually, the tree will be built recursively.

So where did I go wrong? Why does the Children property end up being undefined?

网友答案:
self.Children = isDefined ? self.addChildren(obj.Children) : [];

You are setting self.Children equal to the return of self.addChildren(). That function has no return.

Here is a couple things I would recommend

function Node(obj) {
    // clean constructor moving function definitions to prototype
    var self = this;

    // ensure that we at least have an object passed in
    obj = obj || {};

    // default values at the top
    self.Id = null;
    self.ParentId = null;
    self.Name = '';
    self.Children = [];
    self.TypeId = null;

    // fold in data with $.extend, no need to specify each key manually
    // third object is to overwrite any added Children as those need to be handled seperately
    $.extend(self, obj, { Children : [] });

    // if we have children, add them using the addChildren method
    if (typeof obj.Children !== undefined && $.isArray(obj.Children)) {
        self.addChildren(obj.Children);
    }
}

// using prototype to reduce memory footprint
Node.prototype.hasChildren = function () {
    return this.Children.length > 0;
};

Node.prototype.hasParent = function () {
    var p = this.ParentId;
    return !(p == null || p == undefined || p == 0);
};

Node.prototype.addChildren = function (objArray) {
    for (var i = 0; i < objArray.length; i++) {
        this.addChild(objArray[i]);
    }
};

Node.prototype.addChild = function (obj) {
    if (obj instanceof Node) {
        this.Children.push(obj);
    } else {
        var n = new Node(obj);
        this.Children.push(n);
    }
};

Node.prototype.removeChild = function (n) {
    var index = this.Children.indexOf(n);
    if (index > -1) {
        this.Children.splice(index, 1);
    }
};

Then I can use this like so:

test = new Node({ Id : "Something", Children : [{ Id : "Interior", Children : [] }] })

Using prototype you reduce the memory footprint and don't create a function reference to each interior function for each Node you create. Each Node one still will reference it's internal data via a this variable.

分享给朋友:
您可能感兴趣的文章:
随机阅读: