简体   繁体   中英

Javascript returns undefined while logs object

selectChildByAttrbuteValue(attribute, value)
    {
        if(this.childNodes.length!=0)
        {
            for(var i=0; i<this.childNodes.length; i++)
            {
                if(typeof this.childNodes[i].attributes[attribute]!="undefined")
                {
                    if(this.childNodes[i].attributes[attribute]==value)
                    {
                        return this.childNodes[i];

                    }else
                    {
                        this.childNodes[i].selectChildByAttrbuteValue(attribute, value);
                    }
                }else
                {
                    this.childNodes[i].selectChildByAttrbuteValue(attribute, value);
                }
            }
        }

    }

this code returns undefined, while when i do console.log(this.childNodes[i]); logs me the object. then i should return it.. but it returns undefined!

FULL CLASS

class Node
{
    constructor(nodeName, nodeType)
    {
        this.nodeName = nodeName;

        this.nodeType = nodeType;
        this.attributes = {};
        this.childNodes = [];
        this.parentNode = null;


    }

    removeChild(node)
    {
        if(node.parentNode!=null)
        {
            for(var i=0; i<this.childNodes.length; i++)
            {
                if(node == this.childNodes[i])
                {
                    this.childNodes.splice(i, 1);
                    node.parentNode = null;
                }
            }
        }
    }

    appendChild(child)
    {
        if(child.parentNode==null)
        {
            this.childNodes.push(child);
            child.parentNode = this;

        }else
        {
            child.parentNode.removeChild(child);
            this.childNodes.push(child);
            child.parentNode = this;

        }
    }

    selectChildByAttrbuteValue(attribute, value)
    {

        if(this.childNodes.length!=0)
        {
            for(var i=0; i<this.childNodes.length; i++)
            {
                if(typeof this.childNodes[i].attributes[attribute]!="undefined")
                {
                    if(this.childNodes[i].attributes[attribute]==value)
                    {
                        return this.childNodes[i];

                    }else
                    {
                        this.childNodes[i].selectChildByAttrbuteValue(attribute, value);
                    }
                }else
                {
                    this.childNodes[i].selectChildByAttrbuteValue(attribute, value);
                }
            }
        }

    }

}

a full class to see ghow exactly it loops.

Xml_Node {
  nodeName: 'row',
  nodeType: 'XML_ELEMENT',
  attributes: { name: 'Lee Pellion', characterID: '93746314' },
  childNodes: [],
  parentNode: 
   Xml_Node {
     nodeName: 'rowset',
     nodeType: 'XML_ELEMENT',
     attributes: 
      { name: 'characters',
        key: 'characterID',
        columns: 'name,characterID' },
     childNodes: [ [Circular] ],
     parentNode: 
      Xml_Node {
        nodeName: 'result',
        nodeType: 'XML_ELEMENT',
        attributes: {},
        childNodes: [Object],
        parentNode: [Object],
        innerText: '' },
     innerText: '' },
  innerText: '' }

Root Object

Xml_Node {
  nodeName: 'root',
  nodeType: 'XML_ELEMENT',
  attributes: {},
  childNodes: 
   [ Xml_Node {
       nodeName: 'currentTime',
       nodeType: 'XML_ELEMENT',
       attributes: {},
       childNodes: [],
       parentNode: [Circular],
       innerText: '2016-12-06 01:20:09' },
     Xml_Node {
       nodeName: 'result',
       nodeType: 'XML_ELEMENT',
       attributes: {},
       childNodes: [Object],
       parentNode: [Circular],
       innerText: '' },
     Xml_Node {
       nodeName: 'cachedUntil',
       nodeType: 'XML_ELEMENT',
       attributes: {},
       childNodes: [],
       parentNode: [Circular],
       innerText: '2017-01-06 01:20:09' } ],
  parentNode: null,
  innerText: '' }

with console log it works but then object just dissapears somewhere!

selectChildByAttributeValue(attribute, value) {

    if (this.childNodes.length != 0) {
        for (var i = 0; i < this.childNodes.length; i++) {

            if (typeof this.childNodes[i].attributes[attribute] != 'undefined') {
                if (this.childNodes[i].attributes[attribute] == value) {
                    console.log(this.childNodes[i]);
                    return this.childNodes[i];
                } else {
                    return this.childNodes[i].selectChildByAttributeValue(attribute, value);
                }
            } else {
                return this.childNodes[i].selectChildByAttributeValue(attribute, value);
            }
        }
    }

EDIT:

As we have talked in the comments and you have provided me with more info, I've come up with the following:

  1. The function should be as followed:

     function selectChildByAttributeValue(attribute, value) { if (this.childNodes.length != 0) { for (var i = 0; i < this.childNodes.length; i++) { if (typeof this.childNodes[i].attributes[attribute] != 'undefined') { if (this.childNodes[i].attributes[attribute] == value) { return this.childNodes[i]; } else { return this.childNodes[i].selectChildByAttributeValue(attribute, value); } } else { return this.childNodes[i].selectChildByAttributeValue(attribute, value); } } } } 

    With the return statements in place, so it can properly return a nested child.

  2. Your main node doesn't have any children, that's why it's returning undefined .
    I did the following in my terminal and I got the right node back.

     const n = new Node('row', 'XML_ELEMENT'); n.appendChild(new Node('rowset', 'XML_ELEMENT')); n.appendChild(new Node('rowset', 'XML_ELEMENT')); n.childNodes[0].attributes = {name: 'characters', key: 'characterID', columnds: 'name, characterID'}; n.selectChildByAttributeValue('name', 'characters'); 

    With the following result:

     Node { nodeName: 'rowset', nodeType: 'XML_ELEMENT', attributes: { name: 'characters', key: 'characterID', columnds: 'name, characterID' }, childNodes: [], parentNode: Node { nodeName: 'row', nodeType: 'XML_ELEMENT', attributes: {}, childNodes: [ [Circular], [Object] ], parentNode: null } } 

My root object (declared as n above) is as followed:

Node {
  nodeName: 'row',
  nodeType: 'XML_ELEMENT',
  attributes: {},
  childNodes: 
   [ Node {
       nodeName: 'rowset',
       nodeType: 'XML_ELEMENT',
       attributes: [Object],
       childNodes: [],
       parentNode: [Circular] },
     Node {
       nodeName: 'rowset',
       nodeType: 'XML_ELEMENT',
       attributes: {},
       childNodes: [],
       parentNode: [Circular] } ],
  parentNode: null }

Old Answer

Your function loops through itself to find something, but only has 1 return statement.
So when it calls itself to look into child values and it returns something, it's not stored in a variable or returned as well, so it's being voided.

You can solve this by placing return before the nested call.
So both this.childNodes[i].selectChildByAttrbuteValue(attribute, value); should be return this.childNodes[i].selectChildByAttrbuteValue(attribute, value); .

Also, there is no default value, so if you're looking for a value, but not a single attribute holds that value, you're also getting undefined .

Small note: You're currently allowing the value null to be accepted in the if statement, this might be unwanted behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM